diff --git a/gen_input/templates/asmjit/CORENAME.cpp.gtl b/gen_input/templates/asmjit/CORENAME.cpp.gtl index 00e86e9..cb0a2b5 100644 --- a/gen_input/templates/asmjit/CORENAME.cpp.gtl +++ b/gen_input/templates/asmjit/CORENAME.cpp.gtl @@ -79,21 +79,36 @@ public: } protected: - using vm_base::get_reg_ptr; + using super::get_ptr_for; +using super::get_reg; + using super::get_reg_for; + using super::load_reg_from_mem; + using super::write_reg_to_mem; + using super::gen_ext; + using super::gen_read_mem; + using super::gen_write_mem; + using super::gen_wait; + using super::gen_leave; + using super::gen_operation; + 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; + void gen_block_prologue(jit_holder& jh) override; + void gen_block_epilogue(jit_holder& jh) override; inline const char *name(size_t index){return traits::reg_aliases.at(index);} + void gen_instr_prologue(jit_holder& jh); + void gen_instr_epilogue(jit_holder& jh); + inline void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause); + template::type> inline S sext(U from) { auto mask = (1ULL< - private: /**************************************************************************** * start opcode definitions @@ -139,12 +154,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\\n${instr.name}_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("${instr.name}_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, ${idx}); - pc=pc+ ${instr.length/8}; - - gen_instr_prologue(jh, pc.val); - cc.comment("\\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+${instr.length/8}; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ <%instr.behavior.eachLine{%>${it} <%}%> @@ -214,11 +231,6 @@ private: } }; -template void debug_fn(CODE_WORD instr) { - volatile CODE_WORD x = instr; - instr = 2 * x; -} - template vm_impl::vm_impl() { this(new ARCH()); } template @@ -232,8 +244,7 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) } template -continuation_e -vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, jit_holder& jh) { +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); @@ -251,10 +262,90 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, f = &this_class::illegal_intruction; return (this->*f)(pc, instr, jh); } +template +void vm_impl::gen_instr_prologue(jit_holder& jh) { + auto& cc = jh.cc; + cc.comment("//(*icount)++;"); + cc.inc(get_ptr_for(jh, traits::ICOUNT)); + cc.comment("//*trap_state=*pending_trap;"); + x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE); + cc.mov(current_trap_state, get_ptr_for(jh, traits::TRAP_STATE)); + cc.mov(get_ptr_for(jh, traits::PENDING_TRAP), current_trap_state); -} // namespace ${coreDef.name.toLowerCase()} +} +template +void vm_impl::gen_instr_epilogue(jit_holder& jh) { + auto& cc = jh.cc; + + cc.comment("//if(*trap_state!=0) goto trap_entry;"); + x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE); + cc.mov(current_trap_state, get_ptr_for(jh, traits::TRAP_STATE)); + cc.cmp(current_trap_state, 0); + cc.jne(jh.trap_entry); + + // TODO: Does not need to be done for every instruction, only when needed (by plugin) + cc.comment("//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); +} +template +void vm_impl::gen_block_prologue(jit_holder& jh){ + + jh.pc = load_reg_from_mem(jh, traits::PC); + jh.next_pc = load_reg_from_mem(jh, traits::NEXT_PC); +} +template +void vm_impl::gen_block_epilogue(jit_holder& jh){ + x86::Compiler& cc = jh.cc; + cc.comment("//return *next_pc;"); + cc.ret(jh.next_pc); + + cc.bind(jh.trap_entry); + cc.comment("//Prepare for enter_trap;"); + // Make sure cached values are written back + cc.comment("//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_ptr_for(jh, traits::TRAP_STATE)); + + x86::Gp current_pc = get_reg_for(jh, traits::PC); + cc.mov(current_pc, get_ptr_for(jh, traits::PC)); + + x86::Gp instr = cc.newInt32("instr"); + cc.mov(instr, 0); // this is not correct + cc.comment("//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_ptr_for(jh, traits::NEXT_PC)); + cc.mov(jh.next_pc, current_next_pc); + + cc.comment("//*last_branch = std::numeric_limits::max();"); + cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), std::numeric_limits::max()); + cc.comment("//return *next_pc;"); + cc.ret(jh.next_pc); +} +template +inline void vm_impl:: 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_ptr_for(jh, traits::TRAP_STATE), tmp1); + cc.mov(jh.next_pc, std::numeric_limits::max()); +} + +} // namespace tgc5c template <> std::unique_ptr create(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { @@ -265,9 +356,9 @@ std::unique_ptr create(arch::${coreD } // namespace asmjit } // namespace iss -#include #include #include +#include namespace iss { namespace { volatile std::array dummy = { diff --git a/src/main.cpp b/src/main.cpp index 839bbbc..e4ad4c3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -75,7 +75,7 @@ int main(int argc, char* argv[]) { ("elf,f", po::value>(), "ELF file(s) to load") ("mem,m", po::value(), "the memory input file") ("plugin,p", po::value>(), "plugin to activate") - ("backend", po::value()->default_value("interp"), "the ISS backend to use, options are: interp, tcc") + ("backend", po::value()->default_value("interp"), "the ISS backend to use, options are: interp, llvm, tcc, asmjit") ("isa", po::value()->default_value("tgc5c"), "core or isa name to use for simulation, use '?' to get list"); // clang-format on auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); diff --git a/src/vm/asmjit/helper_func.h b/src/vm/asmjit/helper_func.h deleted file mode 100644 index 88aceba..0000000 --- a/src/vm/asmjit/helper_func.h +++ /dev/null @@ -1,539 +0,0 @@ -#include -#include - -x86::Mem get_reg_ptr(jit_holder& jh, unsigned idx) { - - x86::Gp tmp_ptr = jh.cc.newUIntPtr("tmp_ptr"); - jh.cc.mov(tmp_ptr, jh.regs_base_ptr); - jh.cc.add(tmp_ptr, traits::reg_byte_offsets[idx]); - switch(traits::reg_bit_widths[idx]) { - case 8: - return x86::ptr_8(tmp_ptr); - case 16: - return x86::ptr_16(tmp_ptr); - case 32: - return x86::ptr_32(tmp_ptr); - case 64: - return x86::ptr_64(tmp_ptr); - default: - throw std::runtime_error("Invalid reg size in get_reg_ptr"); - } -} -x86::Gp get_reg_for(jit_holder& jh, unsigned idx) { - // 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(); - case 16: - return jh.cc.newInt16(); - case 32: - return jh.cc.newInt32(); - case 64: - return jh.cc.newInt64(); - default: - throw std::runtime_error("Invalid reg size in get_reg_ptr"); - } -} -x86::Gp get_reg_for(jit_holder& jh, unsigned size, bool is_signed) { - if(is_signed) - switch(size) { - case 8: - return jh.cc.newInt8(); - case 16: - return jh.cc.newInt16(); - case 32: - return jh.cc.newInt32(); - case 64: - return jh.cc.newInt64(); - default: - throw std::runtime_error("Invalid reg size in get_reg_ptr"); - } - else - switch(size) { - case 8: - return jh.cc.newUInt8(); - case 16: - return jh.cc.newUInt16(); - case 32: - return jh.cc.newUInt32(); - case 64: - return jh.cc.newUInt64(); - default: - throw std::runtime_error("Invalid reg size in get_reg_ptr"); - } -} -inline x86::Gp load_reg_from_mem(jit_holder& jh, unsigned idx) { - auto ptr = get_reg_ptr(jh, idx); - auto reg = get_reg_for(jh, idx); - jh.cc.mov(reg, ptr); - return reg; -} -inline void write_reg_to_mem(jit_holder& jh, x86::Gp reg, unsigned idx) { - auto ptr = get_reg_ptr(jh, idx); - jh.cc.mov(ptr, reg); -} - -void gen_instr_prologue(jit_holder& jh, addr_t pc) { - auto& cc = jh.cc; - cc.mov(jh.pc, pc); - - cc.comment("\n//(*icount)++;"); - cc.inc(get_reg_ptr(jh, traits::ICOUNT)); - - cc.comment("\n//*pc=*next_pc;"); - cc.mov(get_reg_ptr(jh, traits::PC), jh.next_pc); - - cc.comment("\n//*trap_state=*pending_trap;"); - 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); -} -void gen_instr_epilogue(jit_holder& jh) { - auto& cc = jh.cc; - - cc.comment("\n//if(*trap_state!=0) goto 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); - - // 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); -} -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); -} -void gen_block_epilogue(jit_holder& jh) override { - x86::Compiler& cc = jh.cc; - cc.comment("\n//return *next_pc;"); - cc.ret(jh.next_pc); - - cc.bind(jh.trap_entry); - 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)); - - x86::Gp current_pc = get_reg_for(jh, traits::PC); - cc.mov(current_pc, get_reg_ptr(jh, traits::PC)); - - x86::Gp instr = cc.newInt32("instr"); - 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); -} -/* - 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 }; - -template ::value || std::is_same::value>> -x86::Gp gen_operation(jit_holder& jh, operation op, x86::Gp a, T b) { - x86::Compiler& cc = jh.cc; - switch(op) { - case add: { - cc.add(a, b); - break; - } - case sub: { - cc.sub(a, b); - break; - } - case band: { - cc.and_(a, b); - break; - } - case bor: { - cc.or_(a, b); - break; - } - case bxor: { - cc.xor_(a, b); - break; - } - case shl: { - cc.shl(a, b); - break; - } - case sar: { - cc.sar(a, b); - break; - } - case shr: { - cc.shr(a, b); - break; - } - default: - throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (operation)", op)); - } - return a; -} - -enum three_operand_operation { imul, mul, idiv, div, srem, urem }; - -x86::Gp gen_operation(jit_holder& jh, three_operand_operation op, x86::Gp a, x86::Gp b) { - x86::Compiler& cc = jh.cc; - switch(op) { - case imul: { - x86::Gp dummy = cc.newInt64(); - cc.imul(dummy, a.r64(), b.r64()); - return a; - } - case mul: { - x86::Gp dummy = cc.newInt64(); - cc.mul(dummy, a.r64(), b.r64()); - return a; - } - case idiv: { - x86::Gp dummy = cc.newInt64(); - cc.mov(dummy, 0); - cc.idiv(dummy, a.r64(), b.r64()); - return a; - } - case div: { - x86::Gp dummy = cc.newInt64(); - cc.mov(dummy, 0); - cc.div(dummy, a.r64(), b.r64()); - return a; - } - case srem: { - x86::Gp rem = cc.newInt32(); - cc.mov(rem, 0); - auto a_reg = cc.newInt32(); - cc.mov(a_reg, a.r32()); - cc.idiv(rem, a_reg, b.r32()); - return rem; - } - case urem: { - x86::Gp rem = cc.newInt32(); - cc.mov(rem, 0); - auto a_reg = cc.newInt32(); - cc.mov(a_reg, a.r32()); - cc.div(rem, a_reg, b.r32()); - return rem; - } - - default: - throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (three_operand)", op)); - } - return a; -} -template ::value>> -x86::Gp gen_operation(jit_holder& jh, three_operand_operation op, x86::Gp a, T b) { - x86::Gp b_reg = jh.cc.newInt32(); - /* switch(a.size()){ - case 1: b_reg = jh.cc.newInt8(); break; - case 2: b_reg = jh.cc.newInt16(); break; - case 4: b_reg = jh.cc.newInt32(); break; - case 8: b_reg = jh.cc.newInt64(); break; - default: throw std::runtime_error(fmt::format("Invalid size ({}) in gen operation", a.size())); - } */ - jh.cc.mov(b_reg, b); - return gen_operation(jh, op, a, b_reg); -} -enum comparison_operation { land, lor, eq, ne, lt, ltu, gt, gtu, lte, lteu, gte, gteu }; - -template ::value || std::is_same::value>> -x86::Gp gen_operation(jit_holder& jh, comparison_operation op, x86::Gp a, T b) { - x86::Compiler& cc = jh.cc; - x86::Gp tmp = cc.newInt8(); - cc.mov(tmp, 1); - Label label_then = cc.newLabel(); - cc.cmp(a, b); - switch(op) { - case eq: - cc.je(label_then); - break; - case ne: - cc.jne(label_then); - break; - case lt: - cc.jl(label_then); - break; - case ltu: - cc.jb(label_then); - break; - case gt: - cc.jg(label_then); - break; - case gtu: - cc.ja(label_then); - break; - case lte: - cc.jle(label_then); - break; - case lteu: - cc.jbe(label_then); - break; - case gte: - cc.jge(label_then); - break; - case gteu: - cc.jae(label_then); - break; - case land: { - Label label_false = cc.newLabel(); - cc.cmp(a, 0); - cc.je(label_false); - auto b_reg = cc.newInt8(); - cc.mov(b_reg, b); - cc.cmp(b_reg, 0); - cc.je(label_false); - cc.jmp(label_then); - cc.bind(label_false); - break; - } - case lor: { - cc.cmp(a, 0); - cc.jne(label_then); - auto b_reg = cc.newInt8(); - cc.mov(b_reg, b); - cc.cmp(b_reg, 0); - cc.jne(label_then); - break; - } - default: - throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (comparison)", op)); - } - cc.mov(tmp, 0); - cc.bind(label_then); - return tmp; -} -enum binary_operation { lnot, inc, dec, bnot, neg }; - -x86::Gp gen_operation(jit_holder& jh, binary_operation op, x86::Gp a) { - x86::Compiler& cc = jh.cc; - switch(op) { - case lnot: - throw std::runtime_error("Current operation not supported in gen_operation(lnot)"); - case inc: { - cc.inc(a); - break; - } - case dec: { - cc.dec(a); - break; - } - case bnot: { - cc.not_(a); - break; - } - case neg: { - cc.neg(a); - break; - } - default: - throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (unary)", op)); - } - return a; -} - -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, is_signed); - jh.cc.mov(val_reg, val); - return gen_ext(jh, val_reg, size, is_signed); -} -inline x86::Gp gen_ext(jit_holder& jh, x86::Gp val, unsigned size, bool is_signed) { - auto& cc = jh.cc; - if(is_signed) { - switch(val.size()) { - case 1: - cc.cbw(val); - break; - case 2: - cc.cwde(val); - break; - case 4: - cc.cdqe(val); - break; - case 8: - break; - default: - throw std::runtime_error("Invalid register size in gen_ext"); - } - } - switch(size) { - case 8: - cc.and_(val, std::numeric_limits::max()); - return val.r8(); - case 16: - cc.and_(val, std::numeric_limits::max()); - return val.r16(); - case 32: - cc.and_(val, std::numeric_limits::max()); - return val.r32(); - case 64: - cc.and_(val, std::numeric_limits::max()); - return val.r64(); - case 128: - return val.r64(); - default: - 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(); - - auto mem_type_reg = cc.newInt32(); - cc.mov(mem_type_reg, type); - - auto space_reg = cc.newInt32(); - cc.mov(space_reg, static_cast(iss::address_type::VIRTUAL)); - - auto val_ptr = cc.newUIntPtr(); - cc.mov(val_ptr, read_mem_buf); - - InvokeNode* invokeNode; - uint64_t mask = 0; - x86::Gp val_reg = cc.newInt64(); - - switch(length) { - case 1: { - cc.invoke(&invokeNode, &read_mem1, FuncSignatureT()); - mask = std::numeric_limits::max(); - break; - } - case 2: { - cc.invoke(&invokeNode, &read_mem2, FuncSignatureT()); - mask = std::numeric_limits::max(); - break; - } - case 4: { - cc.invoke(&invokeNode, &read_mem4, FuncSignatureT()); - mask = std::numeric_limits::max(); - break; - } - case 8: { - cc.invoke(&invokeNode, &read_mem8, FuncSignatureT()); - mask = std::numeric_limits::max(); - break; - } - default: - throw std::runtime_error(fmt::format("Invalid length ({}) in gen_read_mem", length)); - } - - invokeNode->setRet(0, ret_reg); - invokeNode->setArg(0, jh.arch_if_ptr); - invokeNode->setArg(1, space_reg); - 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); - return val_reg; -} -inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp 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) { - 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(); - jh.cc.mov(addr_reg, addr); - - 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, 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, length); -} -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; - switch(length) { - case 1: - cc.invoke(&invokeNode, &write_mem1, FuncSignatureT()); - - 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); - invokeNode->setArg(2, mem_type_reg); - invokeNode->setArg(3, addr); - invokeNode->setArg(4, val); - - 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, uint32_t length) { - auto addr_reg = jh.cc.newUInt64(); - jh.cc.mov(addr_reg, addr); - 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, uint32_t length) { - auto val_reg = get_reg_for(jh, length * 8, true); - jh.cc.mov(val_reg, val); - - auto addr_reg = jh.cc.newUInt64(); - jh.cc.mov(addr_reg, addr); - gen_write_mem(jh, type, addr_reg, val_reg, length); -} diff --git a/src/vm/asmjit/vm_tgc5c.cpp b/src/vm/asmjit/vm_tgc5c.cpp index 1669219..8e4f72b 100644 --- a/src/vm/asmjit/vm_tgc5c.cpp +++ b/src/vm/asmjit/vm_tgc5c.cpp @@ -80,7 +80,7 @@ public: protected: using super::get_ptr_for; - using super::get_reg; +using super::get_reg; using super::get_reg_for; using super::load_reg_from_mem; using super::write_reg_to_mem; @@ -99,7 +99,7 @@ protected: void gen_block_epilogue(jit_holder& jh) override; inline const char *name(size_t index){return traits::reg_aliases.at(index);} - void gen_instr_prologue(jit_holder& jh, addr_t pc); + void gen_instr_prologue(jit_holder& jh); void gen_instr_epilogue(jit_holder& jh); inline void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause); @@ -329,12 +329,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nLUI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("LUI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 0); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -373,12 +375,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nAUIPC_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("AUIPC_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 1); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -417,12 +421,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nJAL_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("JAL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 2); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -470,12 +476,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nJALR_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("JALR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 3); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -483,14 +491,11 @@ private: 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)) + (gen_operation(jh, band, (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm)) + ), addr_mask) ), 32, true); auto label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, urem, - new_pc, static_cast(traits::INSTR_ALIGNMENT)) + cc.cmp(gen_operation(jh, urem, new_pc, static_cast(traits::INSTR_ALIGNMENT)) ,0); auto label_else = cc.newLabel(); cc.je(label_else); @@ -539,20 +544,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nBEQ_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("BEQ_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 4); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ 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)) + 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); { @@ -596,20 +602,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nBNE_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("BNE_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 5); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ 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)) + 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); { @@ -653,22 +660,23 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nBLT_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("BLT_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 6); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ 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)) + 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); { @@ -712,22 +720,23 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nBGE_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("BGE_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 7); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ 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)) + 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); { @@ -771,20 +780,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nBLTU_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("BLTU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 8); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ 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)) + 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); { @@ -828,20 +838,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nBGEU_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("BGEU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 9); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ 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)) + 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); { @@ -885,20 +896,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nLB_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("LB_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 10); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm)) ), 32, true); auto res = gen_ext(jh, gen_read_mem(jh, traits::MEM, load_address, 1), 8, false); @@ -937,20 +949,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nLH_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("LH_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 11); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm)) ), 32, true); auto res = gen_ext(jh, gen_read_mem(jh, traits::MEM, load_address, 2), 16, false); @@ -989,20 +1002,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nLW_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("LW_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 12); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm)) ), 32, true); auto res = gen_ext(jh, gen_read_mem(jh, traits::MEM, load_address, 4), 32, false); @@ -1041,20 +1055,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nLBU_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("LBU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 13); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm)) ), 32, true); auto res = gen_read_mem(jh, traits::MEM, load_address, 1); if(rd!= 0){ @@ -1092,20 +1107,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nLHU_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("LHU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 14); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm)) ), 32, true); auto res = gen_read_mem(jh, traits::MEM, load_address, 2); if(rd!= 0){ @@ -1143,20 +1159,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSB_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SB_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 15); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm)) ), 32, true); gen_write_mem(jh, traits::MEM, store_address, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 8, false), 1); @@ -1190,20 +1207,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSH_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SH_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 16); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm)) ), 32, true); gen_write_mem(jh, traits::MEM, store_address, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 16, false), 2); @@ -1237,20 +1255,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSW_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SW_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 17); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm)) ), 32, true); gen_write_mem(jh, traits::MEM, store_address, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, false), 4); @@ -1284,12 +1303,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nADDI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("ADDI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 18); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1298,8 +1319,7 @@ private: if(rd!= 0){ cc.mov(get_ptr_for(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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm)) ), 32, true)); } } @@ -1332,12 +1352,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSLTI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SLTI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 19); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1392,12 +1414,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSLTIU_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SLTIU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 20); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1451,12 +1475,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nXORI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("XORI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 21); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1464,8 +1490,7 @@ private: else{ if(rd!= 0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), - gen_operation(jh, bxor, - load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm))) + gen_operation(jh, bxor, load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm))) ); } } @@ -1498,12 +1523,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nORI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("ORI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 22); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1511,8 +1538,7 @@ private: else{ if(rd!= 0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), - gen_operation(jh, bor, - load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm))) + gen_operation(jh, bor, load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm))) ); } } @@ -1545,12 +1571,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nANDI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("ANDI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 23); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1558,8 +1586,7 @@ private: else{ if(rd!= 0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), - gen_operation(jh, band, - load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm))) + gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm))) ); } } @@ -1592,12 +1619,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSLLI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SLLI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 24); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1605,8 +1634,7 @@ private: else{ if(rd!= 0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), - gen_operation(jh, shl, - load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, shamt, 32, false)) + gen_operation(jh, shl, load_reg_from_mem(jh, traits::X0 + rs1), shamt) ); } } @@ -1639,12 +1667,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSRLI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SRLI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 25); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1652,8 +1682,7 @@ private: else{ if(rd!= 0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), - gen_operation(jh, shr, - load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, shamt, 32, false)) + gen_operation(jh, shr, load_reg_from_mem(jh, traits::X0 + rs1), shamt) ); } } @@ -1686,12 +1715,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSRAI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SRAI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 26); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1700,9 +1731,8 @@ private: if(rd!= 0){ cc.mov(get_ptr_for(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)) + (gen_operation(jh, sar, gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), shamt) ), 32, true)); } } @@ -1735,12 +1765,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nADD_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("ADD_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 27); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1749,8 +1781,7 @@ private: if(rd!= 0){ cc.mov(get_ptr_for(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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) ), 32, false)); } } @@ -1783,12 +1814,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSUB_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SUB_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 28); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1797,8 +1830,7 @@ private: if(rd!= 0){ cc.mov(get_ptr_for(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)) + (gen_operation(jh, sub, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) ), 32, true)); } } @@ -1831,12 +1863,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSLL_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SLL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 29); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1844,10 +1878,8 @@ private: else{ if(rd!= 0){ cc.mov(get_ptr_for(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)) - )) + gen_ext(jh, gen_operation(jh, shl, load_reg_from_mem(jh, traits::X0 + rs1), (gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs2), (static_cast(traits::XLEN)- 1)) + )) , 32, false)); } } @@ -1880,12 +1912,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSLT_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SLT_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 30); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -1941,12 +1975,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSLTU_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SLTU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 31); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2000,12 +2036,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nXOR_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("XOR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 32); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2013,8 +2051,7 @@ private: else{ if(rd!= 0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), - gen_operation(jh, bxor, - load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + gen_operation(jh, bxor, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) ); } } @@ -2047,12 +2084,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSRL_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SRL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 33); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2060,10 +2099,8 @@ private: else{ if(rd!= 0){ cc.mov(get_ptr_for(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)) - )) + gen_ext(jh, gen_operation(jh, shr, load_reg_from_mem(jh, traits::X0 + rs1), (gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs2), (static_cast(traits::XLEN)- 1)) + )) , 32, false)); } } @@ -2096,12 +2133,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nSRA_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("SRA_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 34); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2110,11 +2149,9 @@ private: if(rd!= 0){ cc.mov(get_ptr_for(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)) - )) + (gen_ext(jh, gen_operation(jh, sar, gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), (gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs2), (static_cast(traits::XLEN)- 1)) + )) , 32, true)), 32, true)); } } @@ -2147,12 +2184,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nOR_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("OR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 35); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2160,8 +2199,7 @@ private: else{ if(rd!= 0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), - gen_operation(jh, bor, - load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + gen_operation(jh, bor, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) ); } } @@ -2194,12 +2232,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nAND_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("AND_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 36); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2207,8 +2247,7 @@ private: else{ if(rd!= 0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), - gen_operation(jh, band, - load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) ); } } @@ -2243,12 +2282,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nFENCE_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("FENCE_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 37); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ gen_write_mem(jh, traits::FENCE, static_cast(traits::fence), (uint8_t)pred<< 4|succ, 4); auto returnValue = CONT; @@ -2276,12 +2317,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nECALL_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("ECALL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 38); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ gen_raise(jh, 0, 11); auto returnValue = TRAP; @@ -2309,12 +2352,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nEBREAK_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("EBREAK_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 39); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ gen_raise(jh, 0, 3); auto returnValue = TRAP; @@ -2342,12 +2387,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nMRET_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("MRET_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 40); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ gen_leave(jh, 3); auto returnValue = TRAP; @@ -2375,12 +2422,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nWFI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("WFI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 41); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ gen_wait(jh, 1); auto returnValue = CONT; @@ -2412,12 +2461,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nCSRRW_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("CSRRW_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 42); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2463,12 +2514,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nCSRRS_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("CSRRS_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 43); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2477,8 +2530,7 @@ private: 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) + gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, bor, xrd, xrs1) , 4); } if(rd!= 0){ @@ -2515,12 +2567,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nCSRRC_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("CSRRC_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 44); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2529,8 +2583,7 @@ private: 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)) + gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, band, xrd, gen_operation(jh, bnot, xrs1)) , 4); } if(rd!= 0){ @@ -2567,12 +2620,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nCSRRWI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("CSRRWI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 45); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2614,12 +2669,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nCSRRSI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("CSRRSI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 46); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2627,8 +2684,7 @@ private: 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) + gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, bor, xrd, (uint32_t)zimm) , 4); } if(rd!= 0){ @@ -2665,12 +2721,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nCSRRCI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("CSRRCI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 47); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2678,8 +2736,7 @@ private: 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)) + gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, band, xrd, ~ ((uint32_t)zimm)) , 4); } if(rd!= 0){ @@ -2716,12 +2773,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nFENCE_I_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("FENCE_I_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 48); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ gen_write_mem(jh, traits::FENCE, static_cast(traits::fencei), imm, 4); auto returnValue = CONT; @@ -2753,24 +2812,25 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nMUL_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("MUL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 49); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, imul, gen_ext(jh, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), gen_ext(jh, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, true), 64, true)) ), 64, true); if(rd!=0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), @@ -2807,30 +2867,30 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nMULH_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("MULH_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 50); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, imul, gen_ext(jh, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), gen_ext(jh, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 32, true), 64, true)) ), 64, true); if(rd!=0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), gen_ext(jh, - (gen_operation(jh, sar, - res, gen_ext(jh, static_cast(traits::XLEN), 64, false)) + (gen_operation(jh, sar, res, static_cast(traits::XLEN)) ), 32, true)); } } @@ -2863,29 +2923,29 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nMULHSU_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("MULHSU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 51); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, imul, gen_ext(jh, + gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs2), 64, false)) ), 64, true); if(rd!=0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), gen_ext(jh, - (gen_operation(jh, sar, - res, gen_ext(jh, static_cast(traits::XLEN), 64, false)) + (gen_operation(jh, sar, res, static_cast(traits::XLEN)) ), 32, true)); } } @@ -2918,28 +2978,28 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nMULHU_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("MULHU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 52); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, mul, 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)) ), 64, false); if(rd!=0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), gen_ext(jh, - (gen_operation(jh, shr, - res, gen_ext(jh, static_cast(traits::XLEN), 64, false)) + (gen_operation(jh, shr, res, static_cast(traits::XLEN)) ), 32, false)); } } @@ -2972,12 +3032,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nDIV_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("DIV_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 53); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)||rs1>=static_cast(traits::RFS)||rs2>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -2989,20 +3051,16 @@ private: 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)) + cc.cmp(gen_operation(jh, ne, divisor, 0) ,0); auto label_else = cc.newLabel(); cc.je(label_else); { 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)) - ) + cc.cmp(gen_operation(jh, land, gen_operation(jh, eq, load_reg_from_mem(jh, traits::X0 + rs1), MMIN) + , gen_operation(jh, eq, divisor, - 1) + ) ,0); auto label_else = cc.newLabel(); cc.je(label_else); @@ -3015,8 +3073,7 @@ private: { cc.mov(get_ptr_for(jh, traits::X0+ rd), gen_ext(jh, - (gen_operation(jh, idiv, - gen_ext(jh, dividend, 64, true), gen_ext(jh, divisor, 64, true)) + (gen_operation(jh, idiv, dividend, divisor) ), 32, true)); } cc.bind(label_merge); @@ -3059,20 +3116,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nDIVU_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("DIVU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 54); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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 label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, ne, - load_reg_from_mem(jh, traits::X0 + rs2), gen_ext(jh, 0, 32, false)) + cc.cmp(gen_operation(jh, ne, load_reg_from_mem(jh, traits::X0 + rs2), 0) ,0); auto label_else = cc.newLabel(); cc.je(label_else); @@ -3080,8 +3138,7 @@ private: if(rd!=0){ cc.mov(get_ptr_for(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)) + (gen_operation(jh, div, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) ), 32, false)); } } @@ -3124,33 +3181,31 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nREM_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("REM_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 55); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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 label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, ne, - load_reg_from_mem(jh, traits::X0 + rs2), gen_ext(jh, 0, 32, false)) + cc.cmp(gen_operation(jh, ne, load_reg_from_mem(jh, traits::X0 + rs2), 0) ,0); auto label_else = cc.newLabel(); cc.je(label_else); { 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)) - ) + 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), - 1) + ) ,0); auto label_else = cc.newLabel(); cc.je(label_else); @@ -3167,10 +3222,9 @@ private: if(rd!=0){ cc.mov(get_ptr_for(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)) + (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)); } } @@ -3215,28 +3269,28 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nREMU_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("REMU_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 56); - pc=pc+ 4; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+4; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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 label_merge = cc.newLabel(); - cc.cmp(gen_operation(jh, ne, - load_reg_from_mem(jh, traits::X0 + rs2), gen_ext(jh, 0, 32, false)) + cc.cmp(gen_operation(jh, ne, load_reg_from_mem(jh, traits::X0 + rs2), 0) ,0); auto label_else = cc.newLabel(); cc.je(label_else); { if(rd!=0){ cc.mov(get_ptr_for(jh, traits::X0+ rd), - gen_operation(jh, urem, - load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) + gen_operation(jh, urem, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2)) ); } } @@ -3278,18 +3332,19 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__ADDI4SPN_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__ADDI4SPN_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 57); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(imm){ cc.mov(get_ptr_for(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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + 2), imm) ), 32, false)); } else{ @@ -3324,16 +3379,17 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__LW_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__LW_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 58); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1+ 8), uimm) ), 32, false); cc.mov(get_ptr_for(jh, traits::X0+ rd+ 8), gen_ext(jh, @@ -3368,16 +3424,17 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__SW_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__SW_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 59); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1+ 8), uimm) ), 32, false); gen_write_mem(jh, traits::MEM, offs, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2+ 8), 32, false), 4); @@ -3409,12 +3466,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__ADDI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__ADDI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 60); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -3423,8 +3482,7 @@ private: if(rs1!= 0){ cc.mov(get_ptr_for(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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int8_t)sext<6>(imm)) ), 32, true)); } } @@ -3454,12 +3512,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__NOP_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__NOP_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 61); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ auto returnValue = CONT; @@ -3488,12 +3548,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__JAL_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__JAL_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 62); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ cc.mov(get_ptr_for(jh, traits::X0+ 1), (uint32_t)(PC+ 2)); @@ -3528,12 +3590,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__LI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__LI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 63); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -3572,12 +3636,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__LUI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__LUI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 64); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(imm== 0||rd>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -3613,18 +3679,19 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__ADDI16SP_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__ADDI16SP_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 65); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(nzimm){ cc.mov(get_ptr_for(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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + 2), (int16_t)sext<10>(nzimm)) ), 32, true)); } else{ @@ -3656,12 +3723,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\n__reserved_clui_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("__reserved_clui_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 66); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ gen_raise(jh, 0, 2); auto returnValue = CONT; @@ -3692,16 +3761,17 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__SRLI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__SRLI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 67); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ cc.mov(get_ptr_for(jh, traits::X0+ rs1+ 8), - gen_operation(jh, shr, - load_reg_from_mem(jh, traits::X0 + rs1+ 8), gen_ext(jh, shamt, 32, false)) + gen_operation(jh, shr, load_reg_from_mem(jh, traits::X0 + rs1+ 8), shamt) ); auto returnValue = CONT; @@ -3731,28 +3801,28 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__SRAI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__SRAI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 68); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(shamt){ cc.mov(get_ptr_for(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)) + (gen_operation(jh, sar, (gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1+ 8), 32, false)), shamt) ), 32, true)); } else{ if(static_cast(traits::XLEN)== 128){ cc.mov(get_ptr_for(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)) + (gen_operation(jh, sar, (gen_ext(jh, + load_reg_from_mem(jh, traits::X0 + rs1+ 8), 32, false)), 64) ), 32, true)); } } @@ -3784,17 +3854,18 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__ANDI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__ANDI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 69); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ cc.mov(get_ptr_for(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)) + (gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1+ 8), (int8_t)sext<6>(imm)) ), 32, true)); auto returnValue = CONT; @@ -3824,17 +3895,18 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__SUB_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__SUB_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 70); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ cc.mov(get_ptr_for(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)) + (gen_operation(jh, sub, load_reg_from_mem(jh, traits::X0 + rd+ 8), load_reg_from_mem(jh, traits::X0 + rs2+ 8)) ), 32, true)); auto returnValue = CONT; @@ -3864,16 +3936,17 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__XOR_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__XOR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 71); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ cc.mov(get_ptr_for(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)) + 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; @@ -3903,16 +3976,17 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__OR_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__OR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 72); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ cc.mov(get_ptr_for(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)) + 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; @@ -3942,16 +4016,17 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__AND_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__AND_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 73); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ cc.mov(get_ptr_for(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)) + 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; @@ -3980,12 +4055,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__J_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__J_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 74); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm)); cc.mov(jh.next_pc, PC_val_v); @@ -4018,16 +4095,17 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__BEQZ_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__BEQZ_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 75); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + cc.cmp(gen_operation(jh, eq, load_reg_from_mem(jh, traits::X0 + rs1+ 8), 0) ,0); cc.je(label_merge); { @@ -4064,16 +4142,17 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__BNEZ_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__BNEZ_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 76); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + cc.cmp(gen_operation(jh, ne, load_reg_from_mem(jh, traits::X0 + rs1+ 8), 0) ,0); cc.je(label_merge); { @@ -4110,12 +4189,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__SLLI_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__SLLI_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 77); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -4123,8 +4204,7 @@ private: else{ if(rs1!= 0){ cc.mov(get_ptr_for(jh, traits::X0+ rs1), - gen_operation(jh, shl, - load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, nzuimm, 32, false)) + gen_operation(jh, shl, load_reg_from_mem(jh, traits::X0 + rs1), nzuimm) ); } } @@ -4156,20 +4236,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__LWSP_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__LWSP_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 78); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + 2), uimm) ), 32, false); cc.mov(get_ptr_for(jh, traits::X0+ rd), gen_ext(jh, @@ -4204,12 +4285,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__MV_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__MV_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 79); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -4247,16 +4330,17 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__JR_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__JR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 80); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ 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)) + auto PC_val_v = gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1%static_cast(traits::RFS)), ~ 0x1) ; cc.mov(jh.next_pc, PC_val_v); cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U); @@ -4289,12 +4373,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\n__reserved_cmv_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("__reserved_cmv_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 81); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ gen_raise(jh, 0, 2); auto returnValue = CONT; @@ -4325,12 +4411,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__ADD_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__ADD_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 82); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rd>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -4339,8 +4427,7 @@ private: if(rd!= 0){ cc.mov(get_ptr_for(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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rd), load_reg_from_mem(jh, traits::X0 + rs2)) ), 32, false)); } } @@ -4371,12 +4458,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__JALR_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__JALR_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 83); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ if(rs1>=static_cast(traits::RFS)){ gen_raise(jh, 0, 2); @@ -4385,8 +4474,7 @@ private: auto new_pc = load_reg_from_mem(jh, traits::X0 + rs1); cc.mov(get_ptr_for(jh, traits::X0+ 1), (uint32_t)(PC+ 2)); - auto PC_val_v = gen_operation(jh, band, - new_pc, gen_ext(jh, ~ 0x1, 32, false)) + auto PC_val_v = gen_operation(jh, band, new_pc, ~ 0x1) ; cc.mov(jh.next_pc, PC_val_v); cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U); @@ -4416,12 +4504,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__EBREAK_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__EBREAK_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 84); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ gen_raise(jh, 0, 3); auto returnValue = CONT; @@ -4452,20 +4542,21 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nC__SWSP_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("C__SWSP_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 85); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//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)) + (gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + 2), uimm) ), 32, false); gen_write_mem(jh, traits::MEM, offs, gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, false), 4); @@ -4495,12 +4586,14 @@ private: } x86::Compiler& cc = jh.cc; - cc.comment(fmt::format("\nDII_{:#x}:",pc.val).c_str()); + cc.comment(fmt::format("DII_{:#x}:",pc.val).c_str()); this->gen_sync(jh, PRE_SYNC, 86); - pc=pc+ 2; - - gen_instr_prologue(jh, pc.val); - cc.comment("\n//behavior:"); + cc.mov(jh.pc, pc.val); + pc = pc+2; + cc.mov(jh.next_pc, pc.val); + + gen_instr_prologue(jh); + cc.comment("//behavior:"); /*generate behavior*/ gen_raise(jh, 0, 2); auto returnValue = CONT; @@ -4603,36 +4696,30 @@ continuation_e vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned return (this->*f)(pc, instr, jh); } template -void vm_impl::gen_instr_prologue(jit_holder& jh, addr_t pc) { +void vm_impl::gen_instr_prologue(jit_holder& jh) { auto& cc = jh.cc; - cc.mov(jh.pc, pc); - cc.comment("\n//(*icount)++;"); + cc.comment("//(*icount)++;"); cc.inc(get_ptr_for(jh, traits::ICOUNT)); - cc.comment("\n//*pc=*next_pc;"); - cc.mov(get_ptr_for(jh, traits::PC), jh.next_pc); - - cc.comment("\n//*trap_state=*pending_trap;"); + cc.comment("//*trap_state=*pending_trap;"); x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE); cc.mov(current_trap_state, get_ptr_for(jh, traits::TRAP_STATE)); cc.mov(get_ptr_for(jh, traits::PENDING_TRAP), current_trap_state); - cc.comment("\n//increment *next_pc"); - cc.mov(jh.next_pc, pc); } template void vm_impl::gen_instr_epilogue(jit_holder& jh) { auto& cc = jh.cc; - cc.comment("\n//if(*trap_state!=0) goto trap_entry;"); + cc.comment("//if(*trap_state!=0) goto trap_entry;"); x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE); cc.mov(current_trap_state, get_ptr_for(jh, traits::TRAP_STATE)); cc.cmp(current_trap_state, 0); cc.jne(jh.trap_entry); // TODO: Does not need to be done for every instruction, only when needed (by plugin) - cc.comment("\n//write back regs to mem"); + cc.comment("//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); } @@ -4645,13 +4732,13 @@ void vm_impl::gen_block_prologue(jit_holder& jh){ template void vm_impl::gen_block_epilogue(jit_holder& jh){ x86::Compiler& cc = jh.cc; - cc.comment("\n//return *next_pc;"); + cc.comment("//return *next_pc;"); cc.ret(jh.next_pc); cc.bind(jh.trap_entry); - cc.comment("\n//Prepare for enter_trap;"); + cc.comment("//Prepare for enter_trap;"); // Make sure cached values are written back - cc.comment("\n//write back regs to mem"); + cc.comment("//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); @@ -4664,7 +4751,7 @@ void vm_impl::gen_block_epilogue(jit_holder& jh){ x86::Gp instr = cc.newInt32("instr"); cc.mov(instr, 0); // this is not correct - cc.comment("\n//enter trap call;"); + cc.comment("//enter trap call;"); InvokeNode* call_enter_trap; cc.invoke(&call_enter_trap, &enter_trap, FuncSignatureT()); call_enter_trap->setArg(0, jh.arch_if_ptr); @@ -4676,9 +4763,9 @@ void vm_impl::gen_block_epilogue(jit_holder& jh){ cc.mov(current_next_pc, get_ptr_for(jh, traits::NEXT_PC)); cc.mov(jh.next_pc, current_next_pc); - cc.comment("\n//*last_branch = std::numeric_limits::max();"); + cc.comment("//*last_branch = std::numeric_limits::max();"); cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), std::numeric_limits::max()); - cc.comment("\n//return *next_pc;"); + cc.comment("//return *next_pc;"); cc.ret(jh.next_pc); } template @@ -4688,13 +4775,9 @@ inline void vm_impl:: gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t auto tmp1 = get_reg_for(jh, traits::TRAP_STATE); cc.mov(tmp1, 0x80ULL << 24 | (cause << 16) | trap_id); cc.mov(get_ptr_for(jh, traits::TRAP_STATE), tmp1); - auto tmp2 = get_reg_for(jh, traits::NEXT_PC); - cc.mov(tmp2, std::numeric_limits::max()); - cc.mov(get_ptr_for(jh, traits::NEXT_PC), tmp2); + cc.mov(jh.next_pc, std::numeric_limits::max()); } - - } // namespace tgc5c template <>