From 0eb1db0e7e235ada683d8b43110a5d9fa2c2d191 Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Mon, 20 Nov 2023 11:45:52 +0100 Subject: [PATCH] adds functionality, adds working asmjit --- src/iss/arch/riscv_hart_m_p.h | 5 +- src/iss/arch/riscv_hart_msu_vp.h | 11 +- src/iss/arch/riscv_hart_mu_p.h | 5 +- src/vm/asmjit/helper_func.h | 141 +- src/vm/asmjit/vm_tgc5c.cpp | 3835 ++++++++++++++++-------------- 5 files changed, 2114 insertions(+), 1883 deletions(-) diff --git a/src/iss/arch/riscv_hart_m_p.h b/src/iss/arch/riscv_hart_m_p.h index 0109ecc..25dc046 100644 --- a/src/iss/arch/riscv_hart_m_p.h +++ b/src/iss/arch/riscv_hart_m_p.h @@ -320,6 +320,8 @@ protected: unsigned get_reg_num() override { return traits::NUM_REGS; } + unsigned get_reg_size(unsigned num) override { return traits::reg_bit_widths[num]; } + riscv_hart_m_p& arch; }; @@ -822,7 +824,8 @@ iss::status riscv_hart_m_p::write(const address_type type, const acc x |= 0x80; // set pll lock upon writing return iss::Ok; } break; - default: {} + default: { + } } } break; case traits::CSR: { diff --git a/src/iss/arch/riscv_hart_msu_vp.h b/src/iss/arch/riscv_hart_msu_vp.h index 8355d3c..d71db2c 100644 --- a/src/iss/arch/riscv_hart_msu_vp.h +++ b/src/iss/arch/riscv_hart_msu_vp.h @@ -371,6 +371,8 @@ protected: unsigned get_reg_num() override { return traits::NUM_REGS; } + unsigned get_reg_size(unsigned num) override { return traits::reg_bit_widths[num]; } + riscv_hart_msu_vp& arch; }; @@ -802,7 +804,8 @@ iss::status riscv_hart_msu_vp::write(const address_type type, const access x |= 0x80; // set pll lock upon writing return iss::Ok; } break; - default: {} + default: { + } } } break; case traits::CSR: { @@ -1225,9 +1228,9 @@ template typename riscv_hart_msu_vp::phys_addr_t riscv_har break; } else if(!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) { break; - } else if(type == iss::access_type::FETCH ? !(pte & PTE_X) - : type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X)) - : !((pte & PTE_R) && (pte & PTE_W))) { + } else if(type == iss::access_type::FETCH ? !(pte & PTE_X) + : type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X)) + : !((pte & PTE_R) && (pte & PTE_W))) { break; } else if((ppn & ((reg_t(1) << ptshift) - 1)) != 0) { break; diff --git a/src/iss/arch/riscv_hart_mu_p.h b/src/iss/arch/riscv_hart_mu_p.h index 7d4f999..5309877 100644 --- a/src/iss/arch/riscv_hart_mu_p.h +++ b/src/iss/arch/riscv_hart_mu_p.h @@ -347,6 +347,8 @@ protected: unsigned get_reg_num() override { return traits::NUM_REGS; } + unsigned get_reg_size(unsigned num) override { return traits::reg_bit_widths[num]; } + riscv_hart_mu_p& arch; }; @@ -1005,7 +1007,8 @@ iss::status riscv_hart_mu_p::write(const address_type type, const ac x |= 0x80; // set pll lock upon writing return iss::Ok; } break; - default: {} + default: { + } } } break; case traits::CSR: { diff --git a/src/vm/asmjit/helper_func.h b/src/vm/asmjit/helper_func.h index 9d5fd68..f209e46 100644 --- a/src/vm/asmjit/helper_func.h +++ b/src/vm/asmjit/helper_func.h @@ -19,7 +19,7 @@ x86::Mem get_reg_ptr(jit_holder& jh, unsigned idx) { } } x86::Gp get_reg_for(jit_holder& jh, unsigned idx) { - // can check for regs in jh and return them instead of creating new ones + // TODO can check for regs in jh and return them instead of creating new ones switch(traits::reg_bit_widths[idx]) { case 8: return jh.cc.newInt8(); @@ -82,7 +82,9 @@ void gen_instr_prologue(jit_holder& jh, addr_t pc) { cc.mov(get_reg_ptr(jh, traits::PC), jh.next_pc); cc.comment("\n//*trap_state=*pending_trap;"); - cc.mov(get_reg_ptr(jh, traits::PENDING_TRAP), jh.trap_state); + x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE); + cc.mov(current_trap_state, get_reg_ptr(jh, traits::TRAP_STATE)); + cc.mov(get_reg_ptr(jh, traits::PENDING_TRAP), current_trap_state); cc.comment("\n//increment *next_pc"); cc.mov(jh.next_pc, pc); @@ -91,20 +93,20 @@ void gen_instr_epilogue(jit_holder& jh) { auto& cc = jh.cc; cc.comment("\n//if(*trap_state!=0) goto trap_entry;"); - cc.test(jh.trap_state, jh.trap_state); - cc.jnz(jh.trap_entry); + x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE); + cc.mov(current_trap_state, get_reg_ptr(jh, traits::TRAP_STATE)); + cc.cmp(current_trap_state, 0); + cc.jne(jh.trap_entry); - // Does this need to be done after every single instruction? + // TODO: Does not need to be done for every instruction, only when needed cc.comment("\n//write back regs to mem"); write_reg_to_mem(jh, jh.pc, traits::PC); write_reg_to_mem(jh, jh.next_pc, traits::NEXT_PC); - write_reg_to_mem(jh, jh.trap_state, traits::TRAP_STATE); } void gen_block_prologue(jit_holder& jh) override { jh.pc = load_reg_from_mem(jh, traits::PC); jh.next_pc = load_reg_from_mem(jh, traits::NEXT_PC); - jh.trap_state = load_reg_from_mem(jh, traits::TRAP_STATE); } void gen_block_epilogue(jit_holder& jh) override { x86::Compiler& cc = jh.cc; @@ -112,7 +114,12 @@ void gen_block_epilogue(jit_holder& jh) override { cc.ret(jh.next_pc); cc.bind(jh.trap_entry); - cc.comment("\n//enter_trap(core_ptr, *trap_state, *pc, 0);"); + cc.comment("\n//Prepare for enter_trap;"); + // Make sure cached values are written back + cc.comment("\n//write back regs to mem"); + write_reg_to_mem(jh, jh.pc, traits::PC); + write_reg_to_mem(jh, jh.next_pc, traits::NEXT_PC); + this->gen_sync(jh, POST_SYNC, -1); x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE); cc.mov(current_trap_state, get_reg_ptr(jh, traits::TRAP_STATE)); @@ -121,23 +128,43 @@ void gen_block_epilogue(jit_holder& jh) override { cc.mov(current_pc, get_reg_ptr(jh, traits::PC)); x86::Gp instr = cc.newInt32("instr"); - cc.mov(instr, 0); + cc.mov(instr, 0); // this is not correct + cc.comment("\n//enter trap call;"); InvokeNode* call_enter_trap; cc.invoke(&call_enter_trap, &enter_trap, FuncSignatureT()); call_enter_trap->setArg(0, jh.arch_if_ptr); call_enter_trap->setArg(1, current_trap_state); call_enter_trap->setArg(2, current_pc); call_enter_trap->setArg(3, instr); + + x86::Gp current_next_pc = get_reg_for(jh, traits::NEXT_PC); + cc.mov(current_next_pc, get_reg_ptr(jh, traits::NEXT_PC)); + cc.mov(jh.next_pc, current_next_pc); + cc.comment("\n//*last_branch = std::numeric_limits::max();"); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), std::numeric_limits::max()); cc.comment("\n//return *next_pc;"); cc.ret(jh.next_pc); } -// TODO implement - -void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause) { jh.cc.comment("//gen_raise"); } -void gen_wait(jit_holder& jh, unsigned type) { jh.cc.comment("//gen_wait"); } -void gen_leave(jit_holder& jh, unsigned lvl) { jh.cc.comment("//gen_leave"); } +/* + inline void raise(uint16_t trap_id, uint16_t cause){ + auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id; + this->core.reg.trap_state = trap_val; + this->template get_reg(traits::NEXT_PC) = std::numeric_limits::max(); + } +*/ +inline void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause) { + auto& cc = jh.cc; + cc.comment("//gen_raise"); + auto tmp1 = get_reg_for(jh, traits::TRAP_STATE); + cc.mov(tmp1, 0x80ULL << 24 | (cause << 16) | trap_id); + cc.mov(get_reg_ptr(jh, traits::TRAP_STATE), tmp1); + auto tmp2 = get_reg_for(jh, traits::NEXT_PC); + cc.mov(tmp2, std::numeric_limits::max()); + cc.mov(get_reg_ptr(jh, traits::NEXT_PC), tmp2); +} +inline void gen_wait(jit_holder& jh, unsigned type) { jh.cc.comment("//gen_wait"); } +inline void gen_leave(jit_holder& jh, unsigned lvl) { jh.cc.comment("//gen_leave"); } enum operation { add, sub, band, bor, bxor, shl, sar, shr }; @@ -342,24 +369,12 @@ x86::Gp gen_operation(jit_holder& jh, binary_operation op, x86::Gp a) { return a; } -/* template -inline typename std::enable_if_t::value, x86::Gp> gen_ext(jit_holder& jh, T val, unsigned size, bool -is_signed) const { auto val_reg = get_reg_for(jh, sizeof(val)*8); auto tmp = get_reg_for(jh, size); jh.cc.mov(val_reg, -val); if(is_signed) jh.cc.movsx(tmp, val_reg); else jh.cc.movzx(tmp,val_reg); return tmp; -} - -template -inline typename std::enable_if_t::value, x86::Gp> gen_ext(jit_holder& jh, T val, unsigned size, bool -is_signed) const { auto val_reg = get_reg_for(jh, sizeof(val)*8); auto tmp = get_reg_for(jh, size); jh.cc.mov(val_reg, -val); if(is_signed) jh.cc.movsx(tmp, val_reg); else jh.cc.movzx(tmp,val_reg); return tmp; -} */ template ::value>> inline x86::Gp gen_ext(jit_holder& jh, T val, unsigned size, bool is_signed) { - auto val_reg = get_reg_for(jh, sizeof(val) * 8); + auto val_reg = get_reg_for(jh, sizeof(val) * 8, is_signed); jh.cc.mov(val_reg, val); return gen_ext(jh, val_reg, size, is_signed); } -// explicit Gp size cast inline x86::Gp gen_ext(jit_holder& jh, x86::Gp val, unsigned size, bool is_signed) { auto& cc = jh.cc; if(is_signed) { @@ -398,7 +413,6 @@ inline x86::Gp gen_ext(jit_holder& jh, x86::Gp val, unsigned size, bool is_signe throw std::runtime_error("Invalid size in gen_ext"); } } - inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, uint32_t length) { x86::Compiler& cc = jh.cc; auto ret_reg = cc.newInt32(); @@ -447,31 +461,18 @@ inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, uint3 invokeNode->setArg(2, mem_type_reg); invokeNode->setArg(3, addr); invokeNode->setArg(4, val_ptr); + cc.cmp(ret_reg, 0); + cc.jne(jh.trap_entry); cc.mov(val_reg, x86::ptr_64(val_ptr)); cc.and_(val_reg, mask); - cc.cmp(ret_reg, 0); - cc.jne(jh.trap_entry); return val_reg; } inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp length) { - uint32_t length_val = 0; - auto length_ptr = jh.cc.newIntPtr(); - jh.cc.mov(length_ptr, &length_val); - jh.cc.mov(x86::ptr_32(length_ptr), length); - - return gen_read_mem(jh, type, addr, length); + throw std::runtime_error("Invalid gen_read_mem"); } inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, x86::Gp length) { - auto addr_reg = jh.cc.newInt64(); - jh.cc.mov(addr_reg, addr); - - uint32_t length_val = 0; - auto length_ptr = jh.cc.newIntPtr(); - jh.cc.mov(length_ptr, &length_val); - jh.cc.mov(x86::ptr_32(length_ptr), length); - - return gen_read_mem(jh, type, addr_reg, length_val); + throw std::runtime_error("Invalid gen_read_mem"); } inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, uint32_t length) { auto addr_reg = jh.cc.newInt64(); @@ -479,32 +480,38 @@ inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, uint return gen_read_mem(jh, type, addr_reg, length); } -inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, int64_t val) { - auto val_reg = jh.cc.newInt64(); +inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, int64_t val, uint32_t length) { + auto val_reg = get_reg_for(jh, length * 8, true); jh.cc.mov(val_reg, val); - gen_write_mem(jh, type, addr, val_reg); + gen_write_mem(jh, type, addr, val_reg, length); } -inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp val) { +inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp val, uint32_t length) { x86::Compiler& cc = jh.cc; - + assert(val.size() == length); auto mem_type_reg = cc.newInt32(); jh.cc.mov(mem_type_reg, type); auto space_reg = cc.newInt32(); jh.cc.mov(space_reg, static_cast(iss::address_type::VIRTUAL)); auto ret_reg = cc.newInt32(); InvokeNode* invokeNode; - - if(val.isGpb()) { + switch(length) { + case 1: cc.invoke(&invokeNode, &write_mem1, FuncSignatureT()); - } else if(val.isGpw()) { - cc.invoke(&invokeNode, &write_mem2, FuncSignatureT()); - } else if(val.isGpd()) { - cc.invoke(&invokeNode, &write_mem4, FuncSignatureT()); - } else if(val.isGpq()) { - cc.invoke(&invokeNode, &write_mem8, FuncSignatureT()); - } else - throw std::runtime_error("Invalid register size in gen_write_mem"); + break; + case 2: + cc.invoke(&invokeNode, &write_mem2, FuncSignatureT()); + break; + case 4: + cc.invoke(&invokeNode, &write_mem4, FuncSignatureT()); + break; + case 8: + cc.invoke(&invokeNode, &write_mem8, FuncSignatureT()); + + break; + default: + throw std::runtime_error("Invalid register size in gen_ext"); + } invokeNode->setRet(0, ret_reg); invokeNode->setArg(0, jh.arch_if_ptr); invokeNode->setArg(1, space_reg); @@ -515,16 +522,16 @@ inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp cc.cmp(ret_reg, 0); cc.jne(jh.trap_entry); } -inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, x86::Gp val) { - auto addr_reg = jh.cc.newInt64(); +inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, x86::Gp val, uint32_t length) { + auto addr_reg = jh.cc.newUInt64(); jh.cc.mov(addr_reg, addr); - gen_write_mem(jh, type, addr_reg, val); + gen_write_mem(jh, type, addr_reg, val, length); } -inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, int64_t val) { - auto val_reg = jh.cc.newInt64(); +inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, int64_t val, uint32_t length) { + auto val_reg = get_reg_for(jh, length * 8, true); jh.cc.mov(val_reg, val); - auto addr_reg = jh.cc.newInt64(); + auto addr_reg = jh.cc.newUInt64(); jh.cc.mov(addr_reg, addr); - gen_write_mem(jh, type, addr_reg, val_reg); + gen_write_mem(jh, type, addr_reg, val_reg, length); } \ No newline at end of file diff --git a/src/vm/asmjit/vm_tgc5c.cpp b/src/vm/asmjit/vm_tgc5c.cpp index ce1c850..b9f792d 100644 --- a/src/vm/asmjit/vm_tgc5c.cpp +++ b/src/vm/asmjit/vm_tgc5c.cpp @@ -29,13 +29,13 @@ * POSSIBILITY OF SUCH DAMAGE. * *******************************************************************************/ - -#include +// clang-format off #include -#include #include #include #include +#include +#include #include #ifndef FMT_HEADER_ONLY @@ -49,6 +49,7 @@ namespace iss { namespace asmjit { + namespace tgc5c { using namespace ::asmjit; using namespace iss::arch; @@ -66,13 +67,13 @@ public: vm_impl(); - vm_impl(ARCH& core, unsigned core_id = 0, unsigned cluster_id = 0); + 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 { + target_adapter_if *accquire_target_adapter(server_if *srv) override { debugger_if::dbg_enabled = true; - if(vm_base::tgt_adapter == nullptr) + if (vm_base::tgt_adapter == nullptr) vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); return vm_base::tgt_adapter; } @@ -82,14 +83,15 @@ protected: using this_class = vm_impl; using compile_func = continuation_e (this_class::*)(virt_addr_t&, code_word_t, jit_holder&); - continuation_e gen_single_inst_behavior(virt_addr_t&, unsigned int&, jit_holder&) override; - inline const char* name(size_t index) { return traits::reg_aliases.at(index); } + continuation_e gen_single_inst_behavior(virt_addr_t&, unsigned int &, jit_holder&) override; + inline const char *name(size_t index){return traits::reg_aliases.at(index);} - template ::type> inline S sext(U from) { - auto mask = (1ULL << W) - 1; - auto sign_mask = 1ULL << (W - 1); + template::type> + inline S sext(U from) { + auto mask = (1ULL< instrs; std::vector children; uint32_t submask = std::numeric_limits::max(); uint32_t value; - decoding_tree_node(uint32_t value) - : value(value) {} + decoding_tree_node(uint32_t value) : value(value){} }; - decoding_tree_node* root{nullptr}; + decoding_tree_node* root {nullptr}; 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, encoding '0b00000000000000000000000000110111' */ {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, /* instruction AUIPC, encoding '0b00000000000000000000000000010111' */ @@ -290,196 +291,211 @@ private: /* instruction DII, encoding '0b0000000000000000' */ {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii}, }}; - + /* instruction definitions */ /* instruction 0: LUI */ - continuation_e __lui(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __lui(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rd = ((bit_sub<7, 5>(instr))); - uint32_t imm = ((bit_sub<12, 20>(instr) << 12)); - if(this->disass_enabled) { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint32_t imm = ((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nLUI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nLUI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 0); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), (uint32_t)((int32_t)imm)); + if(rd>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + (uint32_t)((int32_t)imm)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 0); - return returnValue; + return returnValue; } - + /* instruction 1: AUIPC */ - continuation_e __auipc(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __auipc(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rd = ((bit_sub<7, 5>(instr))); - uint32_t imm = ((bit_sub<12, 20>(instr) << 12)); - if(this->disass_enabled) { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint32_t imm = ((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nAUIPC_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nAUIPC_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 1); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), (uint32_t)(PC + (int32_t)imm)); + if(rd>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + (uint32_t)(PC+(int32_t)imm)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 1); - return returnValue; + return returnValue; } - + /* instruction 2: JAL */ - continuation_e __jal(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __jal(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rd = ((bit_sub<7, 5>(instr))); - uint32_t imm = - ((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) { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint32_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nJAL_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nJAL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 2); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(imm % static_cast(traits::INSTR_ALIGNMENT)) { - gen_raise(jh, 0, 0); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), (uint32_t)(PC + 4)); + if(rd>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(imm%static_cast(traits::INSTR_ALIGNMENT)){ + gen_raise(jh, 0, 0); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + (uint32_t)(PC+ 4)); } - auto PC_val_v = (uint32_t)(PC + (int32_t)sext<21>(imm)); + auto PC_val_v = (uint32_t)(PC+(int32_t)sext<21>(imm)); cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); } } auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 2); - return returnValue; + return returnValue; } - + /* instruction 3: JALR */ - continuation_e __jalr(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __jalr(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nJALR_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nJALR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 3); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto addr_mask = (uint32_t)-2; - auto new_pc = gen_ext(jh, - (gen_operation(jh, band, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, (int16_t)sext<12>(imm), 64, true))), - gen_ext(jh, addr_mask, 64, false))), - 32, true); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto addr_mask = (uint32_t)- 2; + auto new_pc = gen_ext(jh, + (gen_operation(jh, band, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int16_t)sext<12>(imm), 64, true)) + ), gen_ext(jh, addr_mask, 64, false)) + ), 32, true); auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, urem, new_pc, static_cast(traits::INSTR_ALIGNMENT)), 0); + cc.cmp(gen_operation(jh, urem, + new_pc, static_cast(traits::INSTR_ALIGNMENT)) + ,0); auto label_else = cc.newLabel(); cc.je(label_else); - { gen_raise(jh, 0, 0); } + { + gen_raise(jh, 0, 0); + } cc.jmp(label_merge); cc.bind(label_else); - { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), (uint32_t)(PC + 4)); + { + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + (uint32_t)(PC+ 4)); + } + auto PC_val_v = new_pc; + cc.mov(jh.next_pc, PC_val_v); + cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); } - auto PC_val_v = new_pc; - cc.mov(jh.next_pc, PC_val_v); - cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); - } cc.bind(label_merge); } auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 3); - return returnValue; + return returnValue; } - + /* instruction 4: BEQ */ - continuation_e __beq(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __beq(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = - ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nBEQ_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nBEQ_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 4); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs2 >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, eq, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)), 0); + cc.cmp(gen_operation(jh, eq, + load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + ,0); cc.je(label_merge); { - if(imm % static_cast(traits::INSTR_ALIGNMENT)) { - gen_raise(jh, 0, 0); - } else { - auto PC_val_v = (uint32_t)(PC + (int16_t)sext<13>(imm)); + if(imm%static_cast(traits::INSTR_ALIGNMENT)){ + gen_raise(jh, 0, 0); + } + else{ + auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm)); cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); } @@ -487,43 +503,46 @@ private: cc.bind(label_merge); } auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 4); - return returnValue; + return returnValue; } - + /* instruction 5: BNE */ - continuation_e __bne(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __bne(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = - ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nBNE_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nBNE_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 5); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs2 >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, ne, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)), 0); + cc.cmp(gen_operation(jh, ne, + load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + ,0); cc.je(label_merge); { - if(imm % static_cast(traits::INSTR_ALIGNMENT)) { - gen_raise(jh, 0, 0); - } else { - auto PC_val_v = (uint32_t)(PC + (int16_t)sext<13>(imm)); + if(imm%static_cast(traits::INSTR_ALIGNMENT)){ + gen_raise(jh, 0, 0); + } + else{ + auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm)); cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); } @@ -531,45 +550,48 @@ private: cc.bind(label_merge); } auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 5); - return returnValue; + return returnValue; } - + /* instruction 6: BLT */ - continuation_e __blt(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __blt(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = - ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nBLT_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nBLT_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 6); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs2 >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, lt, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, false), - gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, false)), - 0); + cc.cmp(gen_operation(jh, lt, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, false), gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, false)) + ,0); cc.je(label_merge); { - if(imm % static_cast(traits::INSTR_ALIGNMENT)) { - gen_raise(jh, 0, 0); - } else { - auto PC_val_v = (uint32_t)(PC + (int16_t)sext<13>(imm)); + if(imm%static_cast(traits::INSTR_ALIGNMENT)){ + gen_raise(jh, 0, 0); + } + else{ + auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm)); cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); } @@ -577,45 +599,48 @@ private: cc.bind(label_merge); } auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 6); - return returnValue; + return returnValue; } - + /* instruction 7: BGE */ - continuation_e __bge(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __bge(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = - ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nBGE_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nBGE_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 7); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs2 >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, gte, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, false), - gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, false)), - 0); + cc.cmp(gen_operation(jh, gte, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, false), gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, false)) + ,0); cc.je(label_merge); { - if(imm % static_cast(traits::INSTR_ALIGNMENT)) { - gen_raise(jh, 0, 0); - } else { - auto PC_val_v = (uint32_t)(PC + (int16_t)sext<13>(imm)); + if(imm%static_cast(traits::INSTR_ALIGNMENT)){ + gen_raise(jh, 0, 0); + } + else{ + auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm)); cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); } @@ -623,43 +648,46 @@ private: cc.bind(label_merge); } auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 7); - return returnValue; + return returnValue; } - + /* instruction 8: BLTU */ - continuation_e __bltu(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __bltu(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = - ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nBLTU_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nBLTU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 8); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs2 >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, ltu, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)), 0); + cc.cmp(gen_operation(jh, ltu, + load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + ,0); cc.je(label_merge); { - if(imm % static_cast(traits::INSTR_ALIGNMENT)) { - gen_raise(jh, 0, 0); - } else { - auto PC_val_v = (uint32_t)(PC + (int16_t)sext<13>(imm)); + if(imm%static_cast(traits::INSTR_ALIGNMENT)){ + gen_raise(jh, 0, 0); + } + else{ + auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm)); cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); } @@ -667,43 +695,46 @@ private: cc.bind(label_merge); } auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 8); - return returnValue; + return returnValue; } - + /* instruction 9: BGEU */ - continuation_e __bgeu(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __bgeu(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = - ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nBGEU_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nBGEU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 9); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs2 >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, gteu, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)), 0); + cc.cmp(gen_operation(jh, gteu, + load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + ,0); cc.je(label_merge); { - if(imm % static_cast(traits::INSTR_ALIGNMENT)) { - gen_raise(jh, 0, 0); - } else { - auto PC_val_v = (uint32_t)(PC + (int16_t)sext<13>(imm)); + if(imm%static_cast(traits::INSTR_ALIGNMENT)){ + gen_raise(jh, 0, 0); + } + else{ + auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm)); cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); } @@ -711,2773 +742,2954 @@ private: cc.bind(label_merge); } auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 9); - return returnValue; + return returnValue; } - + /* instruction 10: LB */ - continuation_e __lb(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __lb(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nLB_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nLB_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 10); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto load_address = gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, (int16_t)sext<12>(imm), 64, true))), - 32, true); - auto res = gen_ext(jh, gen_read_mem(jh, traits::MEM, load_address, 1), 8, false); - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, res, 32, true)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto load_address = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int16_t)sext<12>(imm), 64, true)) + ), 32, true); + auto res = gen_ext(jh, + gen_read_mem(jh, traits::MEM, load_address, 1), 8, false); + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + res, 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 10); - return returnValue; + return returnValue; } - + /* instruction 11: LH */ - continuation_e __lh(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __lh(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nLH_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nLH_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 11); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto load_address = gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, (int16_t)sext<12>(imm), 64, true))), - 32, true); - auto res = gen_ext(jh, gen_read_mem(jh, traits::MEM, load_address, 2), 16, false); - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, res, 32, true)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto load_address = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int16_t)sext<12>(imm), 64, true)) + ), 32, true); + auto res = gen_ext(jh, + gen_read_mem(jh, traits::MEM, load_address, 2), 16, false); + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + res, 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 11); - return returnValue; + return returnValue; } - + /* instruction 12: LW */ - continuation_e __lw(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __lw(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nLW_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nLW_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 12); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto load_address = gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, (int16_t)sext<12>(imm), 64, true))), - 32, true); - auto res = gen_ext(jh, gen_read_mem(jh, traits::MEM, load_address, 4), 32, false); - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, res, 32, true)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto load_address = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int16_t)sext<12>(imm), 64, true)) + ), 32, true); + auto res = gen_ext(jh, + gen_read_mem(jh, traits::MEM, load_address, 4), 32, false); + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + res, 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 12); - return returnValue; + return returnValue; } - + /* instruction 13: LBU */ - continuation_e __lbu(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __lbu(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nLBU_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nLBU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 13); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto load_address = gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, (int16_t)sext<12>(imm), 64, true))), - 32, true); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto load_address = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int16_t)sext<12>(imm), 64, true)) + ), 32, true); auto res = gen_read_mem(jh, traits::MEM, load_address, 1); - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, res, 32, false)); + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + res, 32, false)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 13); - return returnValue; + return returnValue; } - + /* instruction 14: LHU */ - continuation_e __lhu(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __lhu(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nLHU_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nLHU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 14); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto load_address = gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, (int16_t)sext<12>(imm), 64, true))), - 32, true); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto load_address = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int16_t)sext<12>(imm), 64, true)) + ), 32, true); auto res = gen_read_mem(jh, traits::MEM, load_address, 2); - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, res, 32, false)); + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + res, 32, false)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 14); - return returnValue; + return returnValue; } - + /* instruction 15: SB */ - continuation_e __sb(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __sb(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSB_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSB_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 15); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs2 >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto store_address = gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, (int16_t)sext<12>(imm), 64, true))), - 32, true); - gen_write_mem(jh, traits::MEM, store_address, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 8, false)); + if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto store_address = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int16_t)sext<12>(imm), 64, true)) + ), 32, true); + gen_write_mem(jh, traits::MEM, store_address, gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 8, false), 1); } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 15); - return returnValue; + return returnValue; } - + /* instruction 16: SH */ - continuation_e __sh(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __sh(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSH_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSH_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 16); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs2 >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto store_address = gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, (int16_t)sext<12>(imm), 64, true))), - 32, true); - gen_write_mem(jh, traits::MEM, store_address, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 16, false)); + if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto store_address = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int16_t)sext<12>(imm), 64, true)) + ), 32, true); + gen_write_mem(jh, traits::MEM, store_address, gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 16, false), 2); } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 16); - return returnValue; + return returnValue; } - + /* instruction 17: SW */ - continuation_e __sw(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __sw(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSW_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSW_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 17); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs2 >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto store_address = gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, (int16_t)sext<12>(imm), 64, true))), - 32, true); - gen_write_mem(jh, traits::MEM, store_address, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, false)); + if(rs2>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto store_address = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int16_t)sext<12>(imm), 64, true)) + ), 32, true); + gen_write_mem(jh, traits::MEM, store_address, gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, false), 4); } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 17); - return returnValue; + return returnValue; } - + /* instruction 18: ADDI */ - continuation_e __addi(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __addi(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nADDI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nADDI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 18); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, (int16_t)sext<12>(imm), 64, true))), - 32, true)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int16_t)sext<12>(imm), 64, true)) + ), 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 18); - return returnValue; + return returnValue; } - + /* instruction 19: SLTI */ - continuation_e __slti(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __slti(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSLTI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSLTI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 19); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ { - auto label_then = cc.newLabel(); - auto label_merge = cc.newLabel(); - auto tmp_reg = get_reg_for(jh, 1); - cc.cmp(gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, true), (int16_t)sext<12>(imm)); - cc.jl(label_then); - cc.mov(tmp_reg, 0); - cc.jmp(label_merge); - cc.bind(label_then); - cc.mov(tmp_reg, 1); - cc.bind(label_merge); - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, tmp_reg, 32, false)); + auto label_then = cc.newLabel(); + auto label_merge = cc.newLabel(); + auto tmp_reg = get_reg_for(jh, 1); + cc.cmp(gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), (int16_t)sext<12>(imm)); + cc.jl(label_then); + cc.mov(tmp_reg, 0); + cc.jmp(label_merge); + cc.bind(label_then); + cc.mov(tmp_reg, 1); + cc.bind(label_merge); + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, tmp_reg + , 32, false) + ); } } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 19); - return returnValue; + return returnValue; } - + /* instruction 20: SLTIU */ - continuation_e __sltiu(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __sltiu(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSLTIU_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSLTIU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 20); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ { - auto label_then = cc.newLabel(); - auto label_merge = cc.newLabel(); - auto tmp_reg = get_reg_for(jh, 1); - cc.cmp(load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm))); - cc.jb(label_then); - cc.mov(tmp_reg, 0); - cc.jmp(label_merge); - cc.bind(label_then); - cc.mov(tmp_reg, 1); - cc.bind(label_merge); - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, tmp_reg, 32, false)); + auto label_then = cc.newLabel(); + auto label_merge = cc.newLabel(); + auto tmp_reg = get_reg_for(jh, 1); + cc.cmp(load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm))); + cc.jb(label_then); + cc.mov(tmp_reg, 0); + cc.jmp(label_merge); + cc.bind(label_then); + cc.mov(tmp_reg, 1); + cc.bind(label_merge); + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, tmp_reg + , 32, false) + ); } } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 20); - return returnValue; + return returnValue; } - + /* instruction 21: XORI */ - continuation_e __xori(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __xori(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nXORI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nXORI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 21); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_operation(jh, bxor, load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm)))); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_operation(jh, bxor, + load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm))) + ); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 21); - return returnValue; + return returnValue; } - + /* instruction 22: ORI */ - continuation_e __ori(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __ori(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nORI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nORI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 22); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_operation(jh, bor, load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm)))); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_operation(jh, bor, + load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm))) + ); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 22); - return returnValue; + return returnValue; } - + /* instruction 23: ANDI */ - continuation_e __andi(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __andi(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nANDI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nANDI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 23); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm)))); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_operation(jh, band, + load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm))) + ); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 23); - return returnValue; + return returnValue; } - + /* instruction 24: SLLI */ - continuation_e __slli(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __slli(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSLLI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSLLI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 24); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_operation(jh, shl, load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, shamt, 32, false))); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_operation(jh, shl, + load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, shamt, 32, false)) + ); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 24); - return returnValue; + return returnValue; } - + /* instruction 25: SRLI */ - continuation_e __srli(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __srli(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSRLI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSRLI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 25); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_operation(jh, shr, load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, shamt, 32, false))); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_operation(jh, shr, + load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, shamt, 32, false)) + ); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 25); - return returnValue; + return returnValue; } - + /* instruction 26: SRAI */ - continuation_e __srai(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __srai(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSRAI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSRAI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 26); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, - (gen_operation(jh, sar, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, true), - gen_ext(jh, shamt, 32, false))), - 32, true)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_operation(jh, sar, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), gen_ext(jh, shamt, 32, false)) + ), 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 26); - return returnValue; + return returnValue; } - + /* instruction 27: ADD */ - continuation_e __add(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __add(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nADD_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nADD_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 27); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false))), - 32, false)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false)) + ), 32, false)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 27); - return returnValue; + return returnValue; } - + /* instruction 28: SUB */ - continuation_e __sub(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __sub(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSUB_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSUB_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 28); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, - (gen_operation(jh, sub, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false))), - 32, true)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_operation(jh, sub, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false)) + ), 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 28); - return returnValue; + return returnValue; } - + /* instruction 29: SLL */ - continuation_e __sll(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __sll(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSLL_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSLL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 29); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, - gen_operation(jh, shl, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - (gen_operation(jh, band, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false), - (static_cast(traits::XLEN) - 1)))), - 32, false)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, gen_operation(jh, shl, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), (gen_operation(jh, band, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false), (static_cast(traits::XLEN)- 1)) + )) + , 32, false)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 29); - return returnValue; + return returnValue; } - + /* instruction 30: SLT */ - continuation_e __slt(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __slt(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSLT_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSLT_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 30); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ { - auto label_then = cc.newLabel(); - auto label_merge = cc.newLabel(); - auto tmp_reg = get_reg_for(jh, 1); - cc.cmp(gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, true), - gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, true)); - cc.jl(label_then); - cc.mov(tmp_reg, 0); - cc.jmp(label_merge); - cc.bind(label_then); - cc.mov(tmp_reg, 1); - cc.bind(label_merge); - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, tmp_reg, 32, false)); + auto label_then = cc.newLabel(); + auto label_merge = cc.newLabel(); + auto tmp_reg = get_reg_for(jh, 1); + cc.cmp(gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, true)); + cc.jl(label_then); + cc.mov(tmp_reg, 0); + cc.jmp(label_merge); + cc.bind(label_then); + cc.mov(tmp_reg, 1); + cc.bind(label_merge); + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, tmp_reg + , 32, false) + ); } } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 30); - return returnValue; + return returnValue; } - + /* instruction 31: SLTU */ - continuation_e __sltu(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __sltu(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSLTU_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSLTU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 31); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ { - auto label_then = cc.newLabel(); - auto label_merge = cc.newLabel(); - auto tmp_reg = get_reg_for(jh, 1); - cc.cmp(load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)); - cc.jb(label_then); - cc.mov(tmp_reg, 0); - cc.jmp(label_merge); - cc.bind(label_then); - cc.mov(tmp_reg, 1); - cc.bind(label_merge); - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, tmp_reg, 32, false)); + auto label_then = cc.newLabel(); + auto label_merge = cc.newLabel(); + auto tmp_reg = get_reg_for(jh, 1); + cc.cmp(load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)); + cc.jb(label_then); + cc.mov(tmp_reg, 0); + cc.jmp(label_merge); + cc.bind(label_then); + cc.mov(tmp_reg, 1); + cc.bind(label_merge); + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, tmp_reg + , 32, false) + ); } } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 31); - return returnValue; + return returnValue; } - + /* instruction 32: XOR */ - continuation_e __xor(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __xor(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nXOR_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nXOR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 32); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_operation(jh, bxor, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2))); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_operation(jh, bxor, + load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + ); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 32); - return returnValue; + return returnValue; } - + /* instruction 33: SRL */ - continuation_e __srl(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __srl(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSRL_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSRL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 33); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, - gen_operation(jh, shr, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - (gen_operation(jh, band, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false), - (static_cast(traits::XLEN) - 1)))), - 32, false)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, gen_operation(jh, shr, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), (gen_operation(jh, band, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false), (static_cast(traits::XLEN)- 1)) + )) + , 32, false)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 33); - return returnValue; + return returnValue; } - + /* instruction 34: SRA */ - continuation_e __sra(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __sra(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nSRA_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nSRA_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 34); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, - (gen_ext(jh, - gen_operation( - jh, sar, gen_ext(jh, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), - (gen_operation(jh, band, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false), - (static_cast(traits::XLEN) - 1)))), - 32, true)), - 32, true)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_ext(jh, gen_operation(jh, sar, + gen_ext(jh, gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), (gen_operation(jh, band, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false), (static_cast(traits::XLEN)- 1)) + )) + , 32, true)), 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 34); - return returnValue; + return returnValue; } - + /* instruction 35: OR */ - continuation_e __or(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __or(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nOR_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nOR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 35); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_operation(jh, bor, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2))); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_operation(jh, bor, + load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + ); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 35); - return returnValue; + return returnValue; } - + /* instruction 36: AND */ - continuation_e __and(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __and(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nAND_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nAND_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 36); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2))); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_operation(jh, band, + load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + ); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 36); - return returnValue; + return returnValue; } - + /* instruction 37: FENCE */ - continuation_e __fence(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __fence(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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))); - uint8_t fm = ((bit_sub<28, 4>(instr))); - if(this->disass_enabled) { + 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))); + uint8_t fm = ((bit_sub<28,4>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nFENCE_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nFENCE_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 37); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - gen_write_mem(jh, traits::FENCE, static_cast(traits::fence), (uint8_t)pred << 4 | succ); + gen_write_mem(jh, traits::FENCE, static_cast(traits::fence), (uint8_t)pred<< 4|succ, 4); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 37); - return returnValue; + return returnValue; } - + /* instruction 38: ECALL */ - continuation_e __ecall(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __ecall(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - if(this->disass_enabled) { + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nECALL_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nECALL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 38); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - gen_raise(jh, 0, 11); + gen_raise(jh, 0, 11); auto returnValue = TRAP; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 38); - return returnValue; + return returnValue; } - + /* instruction 39: EBREAK */ - continuation_e __ebreak(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __ebreak(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - if(this->disass_enabled) { + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nEBREAK_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nEBREAK_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 39); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - gen_raise(jh, 0, 3); + gen_raise(jh, 0, 3); auto returnValue = TRAP; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 39); - return returnValue; + return returnValue; } - + /* instruction 40: MRET */ - continuation_e __mret(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __mret(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - if(this->disass_enabled) { + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nMRET_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nMRET_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 40); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ gen_leave(jh, 3); auto returnValue = TRAP; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 40); - return returnValue; + return returnValue; } - + /* instruction 41: WFI */ - continuation_e __wfi(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __wfi(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - if(this->disass_enabled) { + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nWFI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nWFI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 41); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ gen_wait(jh, 1); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 41); - return returnValue; + return returnValue; } - + /* instruction 42: CSRRW */ - continuation_e __csrrw(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __csrrw(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nCSRRW_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nCSRRW_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 42); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto xrs1 = load_reg_from_mem(jh, traits::X0 + rs1); - if(rd != 0) { + if(rd!= 0){ auto xrd = gen_read_mem(jh, traits::CSR, csr, 4); - gen_write_mem(jh, traits::CSR, csr, xrs1); - cc.mov(get_reg_ptr(jh, traits::X0 + rd), xrd); - } else { - gen_write_mem(jh, traits::CSR, csr, xrs1); + gen_write_mem(jh, traits::CSR, csr, xrs1, 4); + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + xrd); + } + else{ + gen_write_mem(jh, traits::CSR, csr, xrs1, 4); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 42); - return returnValue; + return returnValue; } - + /* instruction 43: CSRRS */ - continuation_e __csrrs(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __csrrs(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nCSRRS_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nCSRRS_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 43); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto xrd = gen_read_mem(jh, traits::CSR, csr, 4); auto xrs1 = load_reg_from_mem(jh, traits::X0 + rs1); - if(rs1 != 0) { - gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, bor, xrd, xrs1)); + if(rs1!= 0){ + gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, bor, + xrd, xrs1) + , 4); } - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), xrd); + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + xrd); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 43); - return returnValue; + return returnValue; } - + /* instruction 44: CSRRC */ - continuation_e __csrrc(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __csrrc(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nCSRRC_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nCSRRC_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 44); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto xrd = gen_read_mem(jh, traits::CSR, csr, 4); auto xrs1 = load_reg_from_mem(jh, traits::X0 + rs1); - if(rs1 != 0) { - gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, band, xrd, gen_operation(jh, bnot, xrs1))); + if(rs1!= 0){ + gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, band, + xrd, gen_operation(jh, bnot, xrs1)) + , 4); } - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), xrd); + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + xrd); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 44); - return returnValue; + return returnValue; } - + /* instruction 45: CSRRWI */ - continuation_e __csrrwi(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __csrrwi(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nCSRRWI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nCSRRWI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 45); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rd>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto xrd = gen_read_mem(jh, traits::CSR, csr, 4); - gen_write_mem(jh, traits::CSR, csr, (uint32_t)zimm); - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), xrd); + gen_write_mem(jh, traits::CSR, csr, (uint32_t)zimm, 4); + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + xrd); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 45); - return returnValue; + return returnValue; } - + /* instruction 46: CSRRSI */ - continuation_e __csrrsi(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __csrrsi(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nCSRRSI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nCSRRSI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 46); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rd>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto xrd = gen_read_mem(jh, traits::CSR, csr, 4); - if(zimm != 0) { - gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, bor, xrd, (uint32_t)zimm)); + if(zimm!= 0){ + gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, bor, + xrd, (uint32_t)zimm) + , 4); } - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), xrd); + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + xrd); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 46); - return returnValue; + return returnValue; } - + /* instruction 47: CSRRCI */ - continuation_e __csrrci(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __csrrci(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nCSRRCI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nCSRRCI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 47); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rd>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto xrd = gen_read_mem(jh, traits::CSR, csr, 4); - if(zimm != 0) { - gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, band, xrd, ~((uint32_t)zimm))); + if(zimm!= 0){ + gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, band, + xrd, ~ ((uint32_t)zimm)) + , 4); } - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), xrd); + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + xrd); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 47); - return returnValue; + return returnValue; } - + /* instruction 48: FENCE_I */ - continuation_e __fence_i(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __fence_i(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nFENCE_I_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nFENCE_I_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 48); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - gen_write_mem(jh, traits::FENCE, static_cast(traits::fencei), imm); + gen_write_mem(jh, traits::FENCE, static_cast(traits::fencei), imm, 4); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 48); - return returnValue; + return returnValue; } - + /* instruction 49: MUL */ - continuation_e __mul(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __mul(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nMUL_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nMUL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 49); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto res = gen_ext( - jh, - (gen_operation( - jh, imul, gen_ext(jh, gen_ext(jh, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), 128, true), - gen_ext(jh, gen_ext(jh, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, true), 64, true), 128, true))), - 64, true); - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, res, 32, true)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto res = gen_ext(jh, + (gen_operation(jh, imul, + gen_ext(jh, gen_ext(jh, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), 128, true), gen_ext(jh, gen_ext(jh, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, true), 64, true), 128, true)) + ), 64, true); + if(rd!=0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + res, 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 49); - return returnValue; + return returnValue; } - + /* instruction 50: MULH */ - continuation_e __mulh(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __mulh(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nMULH_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nMULH_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 50); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto res = gen_ext( - jh, - (gen_operation( - jh, imul, gen_ext(jh, gen_ext(jh, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), 128, true), - gen_ext(jh, gen_ext(jh, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, true), 64, true), 128, true))), - 64, true); - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, (gen_operation(jh, sar, res, gen_ext(jh, static_cast(traits::XLEN), 64, false))), 32, true)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto res = gen_ext(jh, + (gen_operation(jh, imul, + gen_ext(jh, gen_ext(jh, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), 128, true), gen_ext(jh, gen_ext(jh, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, true), 64, true), 128, true)) + ), 64, true); + if(rd!=0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_operation(jh, sar, + res, gen_ext(jh, static_cast(traits::XLEN), 64, false)) + ), 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 50); - return returnValue; + return returnValue; } - + /* instruction 51: MULHSU */ - continuation_e __mulhsu(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __mulhsu(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nMULHSU_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nMULHSU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 51); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto res = gen_ext( - jh, - (gen_operation( - jh, imul, gen_ext(jh, gen_ext(jh, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), 128, true), - gen_ext(jh, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false), 128, false))), - 64, true); - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, (gen_operation(jh, sar, res, gen_ext(jh, static_cast(traits::XLEN), 64, false))), 32, true)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto res = gen_ext(jh, + (gen_operation(jh, imul, + gen_ext(jh, gen_ext(jh, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), 128, true), gen_ext(jh, gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 64, false), 128, false)) + ), 64, true); + if(rd!=0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_operation(jh, sar, + res, gen_ext(jh, static_cast(traits::XLEN), 64, false)) + ), 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 51); - return returnValue; + return returnValue; } - + /* instruction 52: MULHU */ - continuation_e __mulhu(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __mulhu(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nMULHU_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nMULHU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 52); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto res = - gen_ext(jh, - (gen_operation(jh, mul, gen_ext(jh, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), 128, false), - gen_ext(jh, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false), 128, false))), - 64, false); - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, (gen_operation(jh, shr, res, gen_ext(jh, static_cast(traits::XLEN), 64, false))), 32, false)); + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto res = gen_ext(jh, + (gen_operation(jh, mul, + gen_ext(jh, gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 64, false), 128, false), gen_ext(jh, gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 64, false), 128, false)) + ), 64, false); + if(rd!=0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_operation(jh, shr, + res, gen_ext(jh, static_cast(traits::XLEN), 64, false)) + ), 32, false)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 52); - return returnValue; + return returnValue; } - + /* instruction 53: DIV */ - continuation_e __div(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __div(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nDIV_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nDIV_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 53); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto dividend = gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, false); - auto divisor = gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, false); - if(rd != 0) { + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto dividend = gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, false); + auto divisor = gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, false); + if(rd!= 0){ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, ne, divisor, gen_ext(jh, 0, 32, false)), 0); + cc.cmp(gen_operation(jh, ne, + divisor, gen_ext(jh, 0, 32, false)) + ,0); auto label_else = cc.newLabel(); cc.je(label_else); { - auto MMIN = ((uint32_t)1) << (static_cast(traits::XLEN) - 1); + auto MMIN = ((uint32_t)1)<<(static_cast(traits::XLEN)-1); auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, land, gen_operation(jh, eq, load_reg_from_mem(jh, traits::X0 + rs1), MMIN), - gen_operation(jh, eq, divisor, gen_ext(jh, -1, 32, true))), - 0); + cc.cmp(gen_operation(jh, land, + gen_operation(jh, eq, + load_reg_from_mem(jh, traits::X0 + rs1), MMIN) + , gen_operation(jh, eq, + divisor, gen_ext(jh, - 1, 32, true)) + ) + ,0); auto label_else = cc.newLabel(); cc.je(label_else); - { cc.mov(get_reg_ptr(jh, traits::X0 + rd), MMIN); } + { + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + MMIN); + } cc.jmp(label_merge); cc.bind(label_else); - { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, (gen_operation(jh, idiv, gen_ext(jh, dividend, 64, true), gen_ext(jh, divisor, 64, true))), 32, - true)); - } + { + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_operation(jh, idiv, + gen_ext(jh, dividend, 64, true), gen_ext(jh, divisor, 64, true)) + ), 32, true)); + } cc.bind(label_merge); } cc.jmp(label_merge); cc.bind(label_else); - { cc.mov(get_reg_ptr(jh, traits::X0 + rd), (uint32_t)-1); } + { + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + (uint32_t)- 1); + } cc.bind(label_merge); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 53); - return returnValue; + return returnValue; } - + /* instruction 54: DIVU */ - continuation_e __divu(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __divu(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nDIVU_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nDIVU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 54); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, ne, load_reg_from_mem(jh, traits::X0 + rs2), gen_ext(jh, 0, 32, false)), 0); + cc.cmp(gen_operation(jh, ne, + load_reg_from_mem(jh, traits::X0 + rs2), gen_ext(jh, 0, 32, false)) + ,0); auto label_else = cc.newLabel(); cc.je(label_else); { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, - (gen_operation(jh, div, load_reg_from_mem(jh, traits::X0 + rs1), - load_reg_from_mem(jh, traits::X0 + rs2))), - 32, false)); + if(rd!=0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_operation(jh, div, + load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + ), 32, false)); } } cc.jmp(label_merge); cc.bind(label_else); - { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), (uint32_t)-1); + { + if(rd!=0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + (uint32_t)- 1); + } } - } cc.bind(label_merge); } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 54); - return returnValue; + return returnValue; } - + /* instruction 55: REM */ - continuation_e __rem(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __rem(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nREM_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nREM_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 55); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, ne, load_reg_from_mem(jh, traits::X0 + rs2), gen_ext(jh, 0, 32, false)), 0); + cc.cmp(gen_operation(jh, ne, + load_reg_from_mem(jh, traits::X0 + rs2), gen_ext(jh, 0, 32, false)) + ,0); auto label_else = cc.newLabel(); cc.je(label_else); { - auto MMIN = (uint32_t)1 << (static_cast(traits::XLEN) - 1); + auto MMIN = (uint32_t)1<<(static_cast(traits::XLEN)-1); auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, land, gen_operation(jh, eq, load_reg_from_mem(jh, traits::X0 + rs1), MMIN), - gen_operation(jh, eq, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, false), - gen_ext(jh, -1, 32, true))), - 0); + cc.cmp(gen_operation(jh, land, + gen_operation(jh, eq, + load_reg_from_mem(jh, traits::X0 + rs1), MMIN) + , gen_operation(jh, eq, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, false), gen_ext(jh, - 1, 32, true)) + ) + ,0); auto label_else = cc.newLabel(); cc.je(label_else); { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, 0, 32, false)); + if(rd!=0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, 0, 32, false) + ); } } cc.jmp(label_merge); cc.bind(label_else); - { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, - (gen_operation(jh, srem, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, false), - gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, false))), - 32, true)); + { + if(rd!=0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_operation(jh, srem, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, false), gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, false)) + ), 32, true)); + } } - } cc.bind(label_merge); } cc.jmp(label_merge); cc.bind(label_else); - { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), load_reg_from_mem(jh, traits::X0 + rs1)); + { + if(rd!=0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + load_reg_from_mem(jh, traits::X0 + rs1)); + } } - } cc.bind(label_merge); } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 55); - return returnValue; + return returnValue; } - + /* instruction 56: REMU */ - continuation_e __remu(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __remu(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nREMU_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nREMU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 56); - pc = pc + 4; - + pc=pc+ 4; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rs1 >= static_cast(traits::RFS) || - rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, ne, load_reg_from_mem(jh, traits::X0 + rs2), gen_ext(jh, 0, 32, false)), 0); + cc.cmp(gen_operation(jh, ne, + load_reg_from_mem(jh, traits::X0 + rs2), gen_ext(jh, 0, 32, false)) + ,0); auto label_else = cc.newLabel(); cc.je(label_else); { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_operation(jh, urem, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2))); + if(rd!=0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_operation(jh, urem, + load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + ); } } cc.jmp(label_merge); cc.bind(label_else); - { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), load_reg_from_mem(jh, traits::X0 + rs1)); + { + if(rd!=0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + load_reg_from_mem(jh, traits::X0 + rs1)); + } } - } cc.bind(label_merge); } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 56); - return returnValue; + return returnValue; } - + /* instruction 57: C__ADDI4SPN */ - continuation_e __c__addi4spn(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__addi4spn(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__ADDI4SPN_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__ADDI4SPN_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 57); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(imm) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd + 8), - gen_ext( - jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + 2), 64, false), gen_ext(jh, imm, 64, false))), - 32, false)); - } else { - gen_raise(jh, 0, 2); + if(imm){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd+ 8), + gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + 2), 64, false), gen_ext(jh, imm, 64, false)) + ), 32, false)); + } + else{ + gen_raise(jh, 0, 2); } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 57); - return returnValue; + return returnValue; } - + /* instruction 58: C__LW */ - continuation_e __c__lw(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__lw(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__LW_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__LW_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 58); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - auto offs = gen_ext( - jh, (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1 + 8), 64, false), gen_ext(jh, uimm, 64, false))), - 32, false); - cc.mov(get_reg_ptr(jh, traits::X0 + rd + 8), gen_ext(jh, gen_ext(jh, gen_read_mem(jh, traits::MEM, offs, 4), 32, false), 32, true)); + auto offs = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1+ 8), 64, false), gen_ext(jh, uimm, 64, false)) + ), 32, false); + cc.mov(get_reg_ptr(jh, traits::X0+ rd+ 8), + gen_ext(jh, + gen_ext(jh, + gen_read_mem(jh, traits::MEM, offs, 4), 32, false), 32, true)); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 58); - return returnValue; + return returnValue; } - + /* instruction 59: C__SW */ - continuation_e __c__sw(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__sw(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__SW_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__SW_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 59); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - auto offs = gen_ext( - jh, (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1 + 8), 64, false), gen_ext(jh, uimm, 64, false))), - 32, false); - gen_write_mem(jh, traits::MEM, offs, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2 + 8), 32, false)); + auto offs = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1+ 8), 64, false), gen_ext(jh, uimm, 64, false)) + ), 32, false); + gen_write_mem(jh, traits::MEM, offs, gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2+ 8), 32, false), 4); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 59); - return returnValue; + return returnValue; } - + /* instruction 60: C__ADDI */ - continuation_e __c__addi(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__addi(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t imm = ((bit_sub<2, 5>(instr)) | (bit_sub<12, 1>(instr) << 5)); - uint8_t rs1 = ((bit_sub<7, 5>(instr))); - if(this->disass_enabled) { + uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__ADDI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__ADDI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 60); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rs1 != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rs1), - gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), - gen_ext(jh, (int8_t)sext<6>(imm), 64, true))), - 32, true)); + if(rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rs1!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rs1), + gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int8_t)sext<6>(imm), 64, true)) + ), 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 60); - return returnValue; + return returnValue; } - + /* instruction 61: C__NOP */ - continuation_e __c__nop(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__nop(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t nzimm = ((bit_sub<2, 5>(instr)) | (bit_sub<12, 1>(instr) << 5)); - if(this->disass_enabled) { + uint8_t nzimm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__NOP_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__NOP_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 61); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 61); - return returnValue; + return returnValue; } - + /* instruction 62: C__JAL */ - continuation_e __c__jal(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__jal(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = - ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__JAL_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__JAL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 62); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - cc.mov(get_reg_ptr(jh, traits::X0 + 1), (uint32_t)(PC + 2)); - auto PC_val_v = (uint32_t)(PC + (int16_t)sext<12>(imm)); + cc.mov(get_reg_ptr(jh, traits::X0+ 1), + (uint32_t)(PC+ 2)); + auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm)); cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 62); - return returnValue; + return returnValue; } - + /* instruction 63: C__LI */ - continuation_e __c__li(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__li(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t imm = ((bit_sub<2, 5>(instr)) | (bit_sub<12, 1>(instr) << 5)); - uint8_t rd = ((bit_sub<7, 5>(instr))); - if(this->disass_enabled) { + uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__LI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__LI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 63); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), (uint32_t)((int8_t)sext<6>(imm))); + if(rd>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + (uint32_t)((int8_t)sext<6>(imm))); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 63); - return returnValue; + return returnValue; } - + /* instruction 64: C__LUI */ - continuation_e __c__lui(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__lui(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint32_t imm = ((bit_sub<2, 5>(instr) << 12) | (bit_sub<12, 1>(instr) << 17)); - uint8_t rd = ((bit_sub<7, 5>(instr))); - if(this->disass_enabled) { + uint32_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__LUI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__LUI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 64); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(imm == 0 || rd >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); + if(imm== 0||rd>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); } - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), (uint32_t)((int32_t)sext<18>(imm))); + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + (uint32_t)((int32_t)sext<18>(imm))); } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 64); - return returnValue; + return returnValue; } - + /* instruction 65: C__ADDI16SP */ - continuation_e __c__addi16sp(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__addi16sp(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t nzimm = ((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) { + uint16_t nzimm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__ADDI16SP_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__ADDI16SP_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 65); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(nzimm) { - cc.mov(get_reg_ptr(jh, traits::X0 + 2), - gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + 2), 64, false), - gen_ext(jh, (int16_t)sext<10>(nzimm), 64, true))), - 32, true)); - } else { - gen_raise(jh, 0, 2); + if(nzimm){ + cc.mov(get_reg_ptr(jh, traits::X0+ 2), + gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + 2), 64, false), gen_ext(jh, (int16_t)sext<10>(nzimm), 64, true)) + ), 32, true)); + } + else{ + gen_raise(jh, 0, 2); } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 65); - return returnValue; + return returnValue; } - + /* instruction 66: __reserved_clui */ - continuation_e ____reserved_clui(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e ____reserved_clui(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rd = ((bit_sub<7, 5>(instr))); - if(this->disass_enabled) { + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\n__reserved_clui_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\n__reserved_clui_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 66); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - gen_raise(jh, 0, 2); + gen_raise(jh, 0, 2); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 66); - return returnValue; + return returnValue; } - + /* instruction 67: C__SRLI */ - continuation_e __c__srli(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__srli(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t shamt = ((bit_sub<2, 5>(instr))); - uint8_t rs1 = ((bit_sub<7, 3>(instr))); - if(this->disass_enabled) { + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__SRLI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__SRLI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 67); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - cc.mov(get_reg_ptr(jh, traits::X0 + rs1 + 8), - gen_operation(jh, shr, load_reg_from_mem(jh, traits::X0 + rs1 + 8), gen_ext(jh, shamt, 32, false))); + cc.mov(get_reg_ptr(jh, traits::X0+ rs1+ 8), + gen_operation(jh, shr, + load_reg_from_mem(jh, traits::X0 + rs1+ 8), gen_ext(jh, shamt, 32, false)) + ); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 67); - return returnValue; + return returnValue; } - + /* instruction 68: C__SRAI */ - continuation_e __c__srai(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__srai(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t shamt = ((bit_sub<2, 5>(instr))); - uint8_t rs1 = ((bit_sub<7, 3>(instr))); - if(this->disass_enabled) { + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__SRAI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__SRAI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 68); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(shamt) { - cc.mov(get_reg_ptr(jh, traits::X0 + rs1 + 8), - gen_ext(jh, - (gen_operation(jh, sar, (gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1 + 8), 32, false)), - gen_ext(jh, shamt, 32, false))), - 32, true)); - } else { - if(static_cast(traits::XLEN) == 128) { - cc.mov(get_reg_ptr(jh, traits::X0 + rs1 + 8), - gen_ext(jh, - (gen_operation(jh, sar, (gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1 + 8), 32, false)), - gen_ext(jh, 64, 32, false))), - 32, true)); + if(shamt){ + cc.mov(get_reg_ptr(jh, traits::X0+ rs1+ 8), + gen_ext(jh, + (gen_operation(jh, sar, + (gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1+ 8), 32, false)), gen_ext(jh, shamt, 32, false)) + ), 32, true)); + } + else{ + if(static_cast(traits::XLEN)== 128){ + cc.mov(get_reg_ptr(jh, traits::X0+ rs1+ 8), + gen_ext(jh, + (gen_operation(jh, sar, + (gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1+ 8), 32, false)), gen_ext(jh, 64, 32, false)) + ), 32, true)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 68); - return returnValue; + return returnValue; } - + /* instruction 69: C__ANDI */ - continuation_e __c__andi(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__andi(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__ANDI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__ANDI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 69); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - cc.mov(get_reg_ptr(jh, traits::X0 + rs1 + 8), - gen_ext(jh, - (gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1 + 8), gen_ext(jh, (int8_t)sext<6>(imm), 32, true))), - 32, true)); + cc.mov(get_reg_ptr(jh, traits::X0+ rs1+ 8), + gen_ext(jh, + (gen_operation(jh, band, + load_reg_from_mem(jh, traits::X0 + rs1+ 8), gen_ext(jh, (int8_t)sext<6>(imm), 32, true)) + ), 32, true)); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 69); - return returnValue; + return returnValue; } - + /* instruction 70: C__SUB */ - continuation_e __c__sub(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__sub(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rs2 = ((bit_sub<2, 3>(instr))); - uint8_t rd = ((bit_sub<7, 3>(instr))); - if(this->disass_enabled) { + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__SUB_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__SUB_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 70); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - cc.mov(get_reg_ptr(jh, traits::X0 + rd + 8), - gen_ext(jh, - (gen_operation(jh, sub, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rd + 8), 64, false), - gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2 + 8), 64, false))), - 32, true)); + cc.mov(get_reg_ptr(jh, traits::X0+ rd+ 8), + gen_ext(jh, + (gen_operation(jh, sub, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rd+ 8), 64, false), gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2+ 8), 64, false)) + ), 32, true)); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 70); - return returnValue; + return returnValue; } - + /* instruction 71: C__XOR */ - continuation_e __c__xor(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__xor(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rs2 = ((bit_sub<2, 3>(instr))); - uint8_t rd = ((bit_sub<7, 3>(instr))); - if(this->disass_enabled) { + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__XOR_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__XOR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 71); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - cc.mov(get_reg_ptr(jh, traits::X0 + rd + 8), - gen_operation(jh, bxor, load_reg_from_mem(jh, traits::X0 + rd + 8), load_reg_from_mem(jh, traits::X0 + rs2 + 8))); + cc.mov(get_reg_ptr(jh, traits::X0+ rd+ 8), + gen_operation(jh, bxor, + load_reg_from_mem(jh, traits::X0 + rd+ 8), load_reg_from_mem(jh, traits::X0 + rs2+ 8)) + ); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 71); - return returnValue; + return returnValue; } - + /* instruction 72: C__OR */ - continuation_e __c__or(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__or(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rs2 = ((bit_sub<2, 3>(instr))); - uint8_t rd = ((bit_sub<7, 3>(instr))); - if(this->disass_enabled) { + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__OR_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__OR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 72); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - cc.mov(get_reg_ptr(jh, traits::X0 + rd + 8), - gen_operation(jh, bor, load_reg_from_mem(jh, traits::X0 + rd + 8), load_reg_from_mem(jh, traits::X0 + rs2 + 8))); + cc.mov(get_reg_ptr(jh, traits::X0+ rd+ 8), + gen_operation(jh, bor, + load_reg_from_mem(jh, traits::X0 + rd+ 8), load_reg_from_mem(jh, traits::X0 + rs2+ 8)) + ); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 72); - return returnValue; + return returnValue; } - + /* instruction 73: C__AND */ - continuation_e __c__and(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__and(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rs2 = ((bit_sub<2, 3>(instr))); - uint8_t rd = ((bit_sub<7, 3>(instr))); - if(this->disass_enabled) { + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__AND_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__AND_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 73); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - cc.mov(get_reg_ptr(jh, traits::X0 + rd + 8), - gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rd + 8), load_reg_from_mem(jh, traits::X0 + rs2 + 8))); + cc.mov(get_reg_ptr(jh, traits::X0+ rd+ 8), + gen_operation(jh, band, + load_reg_from_mem(jh, traits::X0 + rd+ 8), load_reg_from_mem(jh, traits::X0 + rs2+ 8)) + ); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 73); - return returnValue; + return returnValue; } - + /* instruction 74: C__J */ - continuation_e __c__j(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__j(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = - ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__J_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__J_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 74); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - auto PC_val_v = (uint32_t)(PC + (int16_t)sext<12>(imm)); + auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm)); cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 74); - return returnValue; + return returnValue; } - + /* instruction 75: C__BEQZ */ - continuation_e __c__beqz(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__beqz(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__BEQZ_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__BEQZ_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 75); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, eq, load_reg_from_mem(jh, traits::X0 + rs1 + 8), gen_ext(jh, 0, 32, false)), 0); + cc.cmp(gen_operation(jh, eq, + load_reg_from_mem(jh, traits::X0 + rs1+ 8), gen_ext(jh, 0, 32, false)) + ,0); cc.je(label_merge); { - auto PC_val_v = (uint32_t)(PC + (int16_t)sext<9>(imm)); + auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm)); cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); } cc.bind(label_merge); auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 75); - return returnValue; + return returnValue; } - + /* instruction 76: C__BNEZ */ - continuation_e __c__bnez(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__bnez(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint16_t imm = ((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) { + uint16_t imm = ((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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__BNEZ_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__BNEZ_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 76); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, ne, load_reg_from_mem(jh, traits::X0 + rs1 + 8), gen_ext(jh, 0, 32, false)), 0); + cc.cmp(gen_operation(jh, ne, + load_reg_from_mem(jh, traits::X0 + rs1+ 8), gen_ext(jh, 0, 32, false)) + ,0); cc.je(label_merge); { - auto PC_val_v = (uint32_t)(PC + (int16_t)sext<9>(imm)); + auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm)); cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); } cc.bind(label_merge); auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 76); - return returnValue; + return returnValue; } - + /* instruction 77: C__SLLI */ - continuation_e __c__slli(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__slli(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t nzuimm = ((bit_sub<2, 5>(instr))); - uint8_t rs1 = ((bit_sub<7, 5>(instr))); - if(this->disass_enabled) { + uint8_t nzuimm = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__SLLI_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__SLLI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 77); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rs1 != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rs1), - gen_operation(jh, shl, load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, nzuimm, 32, false))); + if(rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rs1!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rs1), + gen_operation(jh, shl, + load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, nzuimm, 32, false)) + ); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 77); - return returnValue; + return returnValue; } - + /* instruction 78: C__LWSP */ - continuation_e __c__lwsp(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__lwsp(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__LWSP_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__LWSP_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 78); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS) || rd == 0) { - gen_raise(jh, 0, 2); - } else { - auto offs = gen_ext( - jh, (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + 2), 64, false), gen_ext(jh, uimm, 64, false))), - 32, false); - cc.mov(get_reg_ptr(jh, traits::X0 + rd), gen_ext(jh, gen_ext(jh, gen_read_mem(jh, traits::MEM, offs, 4), 32, false), 32, true)); + if(rd>=static_cast(traits::RFS)||rd== 0){ + gen_raise(jh, 0, 2); + } + else{ + auto offs = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + 2), 64, false), gen_ext(jh, uimm, 64, false)) + ), 32, false); + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + gen_ext(jh, + gen_read_mem(jh, traits::MEM, offs, 4), 32, false), 32, true)); } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 78); - return returnValue; + return returnValue; } - + /* instruction 79: C__MV */ - continuation_e __c__mv(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__mv(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rs2 = ((bit_sub<2, 5>(instr))); - uint8_t rd = ((bit_sub<7, 5>(instr))); - if(this->disass_enabled) { + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__MV_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__MV_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 79); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), load_reg_from_mem(jh, traits::X0 + rs2)); + if(rd>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + load_reg_from_mem(jh, traits::X0 + rs2)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 79); - return returnValue; + return returnValue; } - + /* instruction 80: C__JR */ - continuation_e __c__jr(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__jr(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rs1 = ((bit_sub<7, 5>(instr))); - if(this->disass_enabled) { + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__JR_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__JR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 80); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs1 && rs1 < static_cast(traits::RFS)) { - auto PC_val_v = gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1 % static_cast(traits::RFS)), - gen_ext(jh, ~0x1, 32, false)); + if(rs1&&rs1(traits::RFS)){ + auto PC_val_v = gen_operation(jh, band, + load_reg_from_mem(jh, traits::X0 + rs1%static_cast(traits::RFS)), gen_ext(jh, ~ 0x1, 32, false)) + ; cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); - } else { + } + else{ gen_raise(jh, 0, 2); } auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 80); - return returnValue; + return returnValue; } - + /* instruction 81: __reserved_cmv */ - continuation_e ____reserved_cmv(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e ____reserved_cmv(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - if(this->disass_enabled) { + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\n__reserved_cmv_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\n__reserved_cmv_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 81); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ gen_raise(jh, 0, 2); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 81); - return returnValue; + return returnValue; } - + /* instruction 82: C__ADD */ - continuation_e __c__add(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__add(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rs2 = ((bit_sub<2, 5>(instr))); - uint8_t rd = ((bit_sub<7, 5>(instr))); - if(this->disass_enabled) { + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__ADD_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__ADD_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 82); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rd >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - if(rd != 0) { - cc.mov(get_reg_ptr(jh, traits::X0 + rd), - gen_ext(jh, - (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rd), 64, false), - gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false))), - 32, false)); + if(rd>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + if(rd!= 0){ + cc.mov(get_reg_ptr(jh, traits::X0+ rd), + gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rd), 64, false), gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false)) + ), 32, false)); } } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 82); - return returnValue; + return returnValue; } - + /* instruction 83: C__JALR */ - continuation_e __c__jalr(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__jalr(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - uint8_t rs1 = ((bit_sub<7, 5>(instr))); - if(this->disass_enabled) { + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__JALR_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__JALR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 83); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs1 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { + if(rs1>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ auto new_pc = load_reg_from_mem(jh, traits::X0 + rs1); - cc.mov(get_reg_ptr(jh, traits::X0 + 1), (uint32_t)(PC + 2)); - auto PC_val_v = gen_operation(jh, band, new_pc, gen_ext(jh, ~0x1, 32, false)); + cc.mov(get_reg_ptr(jh, traits::X0+ 1), + (uint32_t)(PC+ 2)); + auto PC_val_v = gen_operation(jh, band, + new_pc, gen_ext(jh, ~ 0x1, 32, false)) + ; cc.mov(jh.next_pc, PC_val_v); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U); } auto returnValue = BRANCH; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 83); - return returnValue; + return returnValue; } - + /* instruction 84: C__EBREAK */ - continuation_e __c__ebreak(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__ebreak(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - if(this->disass_enabled) { + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__EBREAK_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__EBREAK_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 84); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - gen_raise(jh, 0, 3); + gen_raise(jh, 0, 3); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 84); - return returnValue; + return returnValue; } - + /* instruction 85: C__SWSP */ - continuation_e __c__swsp(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __c__swsp(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - 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) { + 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 disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nC__SWSP_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nC__SWSP_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 85); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - if(rs2 >= static_cast(traits::RFS)) { - gen_raise(jh, 0, 2); - } else { - auto offs = gen_ext( - jh, (gen_operation(jh, add, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + 2), 64, false), gen_ext(jh, uimm, 64, false))), - 32, false); - gen_write_mem(jh, traits::MEM, offs, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, false)); + if(rs2>=static_cast(traits::RFS)){ + gen_raise(jh, 0, 2); + } + else{ + auto offs = gen_ext(jh, + (gen_operation(jh, add, + gen_ext(jh, load_reg_from_mem(jh, traits::X0 + 2), 64, false), gen_ext(jh, uimm, 64, false)) + ), 32, false); + gen_write_mem(jh, traits::MEM, offs, gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, false), 4); } auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 85); - return returnValue; + return returnValue; } - + /* instruction 86: DII */ - continuation_e __dii(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { + continuation_e __dii(virt_addr_t& pc, code_word_t instr, jit_holder& jh){ uint64_t PC = pc.val; - if(this->disass_enabled) { + if(this->disass_enabled){ /* generate disass */ } x86::Compiler& cc = jh.cc; - // ideally only do this if necessary (someone / plugin needs it) - cc.mov(jh.pc, PC); - cc.comment(fmt::format("\nDII_{:#x}:", pc.val).c_str()); + //ideally only do this if necessary (someone / plugin needs it) + cc.mov(jh.pc,PC); + cc.comment(fmt::format("\nDII_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 86); - pc = pc + 2; - + pc=pc+ 2; + gen_instr_prologue(jh, pc.val); cc.comment("\n//behavior:"); /*generate behavior*/ - gen_raise(jh, 0, 2); + gen_raise(jh, 0, 2); auto returnValue = CONT; - + gen_instr_epilogue(jh); this->gen_sync(jh, POST_SYNC, 86); - return returnValue; + return returnValue; } - + /**************************************************************************** * end opcode definitions ****************************************************************************/ - continuation_e illegal_intruction(virt_addr_t& pc, code_word_t instr, jit_holder& jh) { return BRANCH; } - // decoding functionality + continuation_e illegal_intruction(virt_addr_t &pc, code_word_t instr, jit_holder& jh ) { - void populate_decoding_tree(decoding_tree_node* root) { - // create submask - for(auto instr : root->instrs) { + return BRANCH; + } + //decoding functionality + + void populate_decoding_tree(decoding_tree_node* root){ + //create submask + for(auto instr: root->instrs){ root->submask &= instr.mask; } - // put each instr according to submask&encoding into children - for(auto instr : root->instrs) { + //put each instr according to submask&encoding into children + for(auto instr: root->instrs){ bool foundMatch = false; - for(auto child : root->children) { - // use value as identifying trait - if(child->value == (instr.value & root->submask)) { + for(auto child: root->children){ + //use value as identifying trait + if(child->value == (instr.value&root->submask)){ child->instrs.push_back(instr); foundMatch = true; } } - if(!foundMatch) { - decoding_tree_node* child = new decoding_tree_node(instr.value & root->submask); + if(!foundMatch){ + decoding_tree_node* child = new decoding_tree_node(instr.value&root->submask); child->instrs.push_back(instr); root->children.push_back(child); } } root->instrs.clear(); - // call populate_decoding_tree for all children - if(root->children.size() > 1) - for(auto child : root->children) { - populate_decoding_tree(child); + //call populate_decoding_tree for all children + if(root->children.size() >1) + for(auto child: root->children){ + populate_decoding_tree(child); } - else { - // sort instrs by value of the mask, this works bc we want to have the least restrictive one last - std::sort(root->children[0]->instrs.begin(), root->children[0]->instrs.end(), - [](const instruction_descriptor& instr1, const instruction_descriptor& instr2) { return instr1.mask > instr2.mask; }); + else{ + //sort instrs by value of the mask, this works bc we want to have the least restrictive one last + std::sort(root->children[0]->instrs.begin(), root->children[0]->instrs.end(), [](const instruction_descriptor& instr1, const instruction_descriptor& instr2) { + return instr1.mask > instr2.mask; + }); } } - compile_func decode_instr(decoding_tree_node* node, code_word_t word) { - if(!node->children.size()) { - if(node->instrs.size() == 1) - return node->instrs[0].op; - for(auto instr : node->instrs) { - if((instr.mask & word) == instr.value) - return instr.op; + compile_func decode_instr(decoding_tree_node* node, code_word_t word){ + if(!node->children.size()){ + if(node->instrs.size() == 1) return node->instrs[0].op; + for(auto instr : node->instrs){ + if((instr.mask&word) == instr.value) return instr.op; } - } else { - for(auto child : node->children) { - if(child->value == (node->submask & word)) { + } + else{ + for(auto child : node->children){ + if (child->value == (node->submask&word)){ return decode_instr(child, word); - } - } + } + } } return nullptr; } @@ -3491,65 +3703,68 @@ template void debug_fn(CODE_WORD instr) { template vm_impl::vm_impl() { this(new ARCH()); } template -vm_impl::vm_impl(ARCH& core, unsigned core_id, unsigned cluster_id) +vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) : vm_base(core, core_id, cluster_id) { root = new decoding_tree_node(std::numeric_limits::max()); - for(auto instr : instr_descr) { + for(auto instr: instr_descr){ root->instrs.push_back(instr); } populate_decoding_tree(root); } -template continuation_e vm_impl::gen_single_inst_behavior(virt_addr_t& pc, unsigned int& inst_cnt, jit_holder& jh) { - enum { TRAP_ID = 1 << 16 }; +template +continuation_e +vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, jit_holder& jh) { + enum {TRAP_ID=1<<16}; code_word_t instr = 0; phys_addr_t paddr(pc); - auto* const data = (uint8_t*)&instr; + auto *const data = (uint8_t *)&instr; if(this->core.has_mmu()) paddr = this->core.virt2phys(pc); auto res = this->core.read(paddr, 4, data); - if(res != iss::Ok) + if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); - if(instr == 0x0000006f || (instr & 0xffff) == 0xa001) + if (instr == 0x0000006f || (instr&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' ++inst_cnt; auto f = decode_instr(root, instr); - if(f == nullptr) + if (f == nullptr) f = &this_class::illegal_intruction; return (this->*f)(pc, instr, jh); } + + } // namespace tgc5c -template <> std::unique_ptr create(arch::tgc5c* core, unsigned short port, bool dump) { +template <> +std::unique_ptr create(arch::tgc5c *core, unsigned short port, bool dump) { auto ret = new tgc5c::vm_impl(*core, dump); - if(port != 0) - debugger::server::run_server(ret, port); + if (port != 0) debugger::server::run_server(ret, port); return std::unique_ptr(ret); } } // namespace asmjit } // namespace iss +#include #include #include -#include namespace iss { namespace { volatile std::array dummy = { - core_factory::instance().register_creator("tgc5c|m_p|asmjit", - [](unsigned port, void*) -> std::tuple { - auto* cpu = new iss::arch::riscv_hart_m_p(); - auto* vm = new asmjit::tgc5c::vm_impl(*cpu, false); - if(port != 0) - debugger::server::run_server(vm, port); - return {cpu_ptr{cpu}, vm_ptr{vm}}; - }), - core_factory::instance().register_creator("tgc5c|mu_p|asmjit", [](unsigned port, void*) -> std::tuple { - auto* cpu = new iss::arch::riscv_hart_mu_p(); - auto* vm = new asmjit::tgc5c::vm_impl(*cpu, false); - if(port != 0) - debugger::server::run_server(vm, port); - return {cpu_ptr{cpu}, vm_ptr{vm}}; - })}; + core_factory::instance().register_creator("tgc5c|m_p|asmjit", [](unsigned port, void*) -> std::tuple{ + auto* cpu = new iss::arch::riscv_hart_m_p(); + auto* vm = new asmjit::tgc5c::vm_impl(*cpu, false); + if (port != 0) debugger::server::run_server(vm, port); + return {cpu_ptr{cpu}, vm_ptr{vm}}; + }), + core_factory::instance().register_creator("tgc5c|mu_p|asmjit", [](unsigned port, void*) -> std::tuple{ + auto* cpu = new iss::arch::riscv_hart_mu_p(); + auto* vm = new asmjit::tgc5c::vm_impl(*cpu, false); + if (port != 0) debugger::server::run_server(vm, port); + return {cpu_ptr{cpu}, vm_ptr{vm}}; + }) +}; } -} // namespace iss +} +// clang-format on \ No newline at end of file