From 264053a8d6ab7d5531405e8d1bf2d033e034d4d6 Mon Sep 17 00:00:00 2001 From: eyck Date: Fri, 17 Apr 2020 19:23:43 +0200 Subject: [PATCH] [WIP] add next increment for TCC --- gen_input/templates/tcc/incl-CORENAME.h.gtl | 4 +- .../templates/tcc/vm-vm_CORENAME.cpp.gtl | 58 +- incl/iss/arch/mnrv32.h | 4 +- incl/iss/arch/riscv_hart_msu_vp.h | 6 +- src/sysc/core_complex.cpp | 2 +- src/vm/tcc/vm_mnrv32.cpp | 952 +++++++++--------- 6 files changed, 517 insertions(+), 509 deletions(-) diff --git a/gen_input/templates/tcc/incl-CORENAME.h.gtl b/gen_input/templates/tcc/incl-CORENAME.h.gtl index 139d39d..0a5b99f 100644 --- a/gen_input/templates/tcc/incl-CORENAME.h.gtl +++ b/gen_input/templates/tcc/incl-CORENAME.h.gtl @@ -172,6 +172,8 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { inline bool should_stop() { return interrupt_sim; } + inline uint64_t stop_code() { return interrupt_sim; } + inline phys_addr_t v2p(const iss::addr_t& addr){ if (addr.space != traits<${coreDef.name.toLowerCase()}>::MEM || addr.type == iss::address_type::PHYSICAL || addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL) { @@ -204,7 +206,7 @@ protected: std::array addr_mode; - bool interrupt_sim=false; + uint64_t interrupt_sim=0; <% def fcsr = allRegs.find {it.name=='FCSR'} if(fcsr != null) {%> diff --git a/gen_input/templates/tcc/vm-vm_CORENAME.cpp.gtl b/gen_input/templates/tcc/vm-vm_CORENAME.cpp.gtl index d3df60a..00c591c 100644 --- a/gen_input/templates/tcc/vm-vm_CORENAME.cpp.gtl +++ b/gen_input/templates/tcc/vm-vm_CORENAME.cpp.gtl @@ -60,7 +60,7 @@ public: using phys_addr_t = typename super::phys_addr_t; using code_word_t = typename super::code_word_t; using addr_t = typename super::addr_t; - using ICmpInst = typename super::ICmpInst; + using tu_builder = typename super::tu_builder; vm_impl(); @@ -77,11 +77,10 @@ public: protected: using vm_base::get_reg_ptr; - using translation_unit = typename vm_base::translation_unit; using this_class = vm_impl; using compile_ret_t = std::tuple; - using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr, translation_unit&); + using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr, tu_builder&); inline const char *name(size_t index){return traits::reg_aliases.at(index);} @@ -89,34 +88,34 @@ protected: super::setup_module(m); } - compile_ret_t gen_single_inst_behavior(virt_addr_t &, unsigned int &, translation_unit&) override; + compile_ret_t gen_single_inst_behavior(virt_addr_t &, unsigned int &, tu_builder&) override; - void gen_trap_behavior(translation_unit& tu) override; + void gen_trap_behavior(tu_builder& tu) override; - void gen_raise_trap(translation_unit& tu, uint16_t trap_id, uint16_t cause); + void gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause); - void gen_leave_trap(translation_unit& tu, unsigned lvl); + void gen_leave_trap(tu_builder& tu, unsigned lvl); - void gen_wait(translation_unit& tu, unsigned type); + void gen_wait(tu_builder& tu, unsigned type); - inline void gen_trap_check(translation_unit& tu) { - tu<<" if(*trap_state!=0) goto trap_entry;"; + inline void gen_trap_check(tu_builder& tu) { + tu("if(*trap_state!=0) goto trap_entry;"); } - inline void gen_set_pc(translation_unit& tu, virt_addr_t pc, unsigned reg_num) { + inline void gen_set_pc(tu_builder& tu, virt_addr_t pc, unsigned reg_num) { switch(reg_num){ case traits::NEXT_PC: - tu(" *next_pc = {:#x};", pc.val); + tu("*next_pc = {:#x};", pc.val); break; case traits::PC: - tu(" *pc = {:#x};", pc.val); + tu("*pc = {:#x};", pc.val); break; default: if(!tu.defined_regs[reg_num]){ - tu(" reg_t* reg{:02d} = (reg_t*){:#x};", reg_num, reinterpret_cast(get_reg_ptr(reg_num))); + tu("reg_t* reg{:02d} = (reg_t*){:#x};", reg_num, reinterpret_cast(get_reg_ptr(reg_num))); tu.defined_regs[reg_num]=true; } - tu(" *reg{:02d} = {:#x};", reg_num, pc.val); + tu("*reg{:02d} = {:#x};", reg_num, pc.val); } } @@ -191,14 +190,14 @@ private: /* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %> /* instruction ${idx}: ${instr.name} */ - compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, translation_unit& tu){<%instr.code.eachLine{%> + compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, tu_builder& tu){<%instr.code.eachLine{%> ${it}<%}%> } <%}%> /**************************************************************************** * end opcode definitions ****************************************************************************/ - compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr, translation_unit& tu) { + compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr, tu_builder& tu) { vm_impl::gen_sync(tu, iss::PRE_SYNC, instr_descr.size()); pc = pc + ((instr & 3) == 3 ? 4 : 2); gen_raise_trap(tu, 0, 2); // illegal instruction trap @@ -230,7 +229,7 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) template std::tuple -vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, translation_unit& tu) { +vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, tu_builder& tu) { // we fetch at max 4 byte, alignment is 2 enum {TRAP_ID=1<<16}; code_word_t insn = 0; @@ -259,24 +258,25 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, return (this->*f)(pc, insn, tu); } -template void vm_impl::gen_raise_trap(translation_unit& tu, uint16_t trap_id, uint16_t cause) { +template void vm_impl::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) { tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id); - tu << tu.create_store(tu.gen_const(32, std::numeric_limits::max()),traits::LAST_BRANCH); + tu.create_store(tu.gen_const(32, std::numeric_limits::max()),traits::LAST_BRANCH); } -template void vm_impl::gen_leave_trap(translation_unit& tu, unsigned lvl) { - tu(" leave_trap(core_ptr, {});", lvl); - tu(" *next_pc = {};", tu.create_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8)); - tu << tu.create_store(tu.gen_const(32, std::numeric_limits::max()),traits::LAST_BRANCH); +template void vm_impl::gen_leave_trap(tu_builder& tu, unsigned lvl) { + tu("leave_trap(core_ptr, {});", lvl); + tu.create_store(tu.create_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8),traits::NEXT_PC); + tu.create_store(tu.gen_const(32, std::numeric_limits::max()),traits::LAST_BRANCH); } -template void vm_impl::gen_wait(translation_unit& tu, unsigned type) { +template void vm_impl::gen_wait(tu_builder& tu, unsigned type) { } -template void vm_impl::gen_trap_behavior(translation_unit& tu) { - tu<<"trap_entry:"; - tu(" enter_trap(core_ptr, *trap_state, *pc);"); - tu(" return *next_pc;"); +template void vm_impl::gen_trap_behavior(tu_builder& tu) { + tu("trap_entry:"); + tu("enter_trap(core_ptr, *trap_state, *pc);"); + tu.create_store(tu.gen_const(32, std::numeric_limits::max()),traits::LAST_BRANCH); + tu("return *next_pc;"); } } // namespace mnrv32 diff --git a/incl/iss/arch/mnrv32.h b/incl/iss/arch/mnrv32.h index 82eac60..33f97ce 100644 --- a/incl/iss/arch/mnrv32.h +++ b/incl/iss/arch/mnrv32.h @@ -182,6 +182,8 @@ struct mnrv32: public arch_if { inline bool should_stop() { return interrupt_sim; } + inline uint64_t stop_code() { return interrupt_sim; } + inline phys_addr_t v2p(const iss::addr_t& addr){ if (addr.space != traits::MEM || addr.type == iss::address_type::PHYSICAL || addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL) { @@ -238,7 +240,7 @@ protected: std::array addr_mode; - bool interrupt_sim=false; + uint64_t interrupt_sim=0; uint32_t get_fcsr(){return 0;} void set_fcsr(uint32_t val){} diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h index 517762d..2410eda 100644 --- a/incl/iss/arch/riscv_hart_msu_vp.h +++ b/incl/iss/arch/riscv_hart_msu_vp.h @@ -1082,7 +1082,10 @@ iss::status riscv_hart_msu_vp::write_mem(phys_addr_t paddr, unsigned lengt LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar << "), stopping simulation"; } - throw(iss::simulation_stopped(hostvar)); + this->reg.trap_state=std::numeric_limits::max(); + this->interrupt_sim=hostvar; + break; + //throw(iss::simulation_stopped(hostvar)); case 0x0101: { char c = static_cast(hostvar & 0xff); if (c == '\n' || c == 0) { @@ -1313,6 +1316,7 @@ template uint64_t riscv_hart_msu_vp::enter_trap(uint64_t f this->reg.trap_state = 0; std::array buffer; sprintf(buffer.data(), "0x%016lx", addr); + if((flags&0xffffffff) != 0xffffffff) CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause]) << "' (" << trap_id << ")" << " at address " << buffer.data() << " occurred, changing privilege level from " diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index 3a7b97b..7061dc9 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -102,7 +102,7 @@ public: uint32_t get_mode() { return this->reg.machine_state; } - inline void set_interrupt_execution(bool v) { this->interrupt_sim = v; } + inline void set_interrupt_execution(bool v) { this->interrupt_sim = v?1:0; } inline bool get_interrupt_execution() { return this->interrupt_sim; } diff --git a/src/vm/tcc/vm_mnrv32.cpp b/src/vm/tcc/vm_mnrv32.cpp index 7a00cda..aec591b 100644 --- a/src/vm/tcc/vm_mnrv32.cpp +++ b/src/vm/tcc/vm_mnrv32.cpp @@ -60,7 +60,7 @@ public: using phys_addr_t = typename super::phys_addr_t; using code_word_t = typename super::code_word_t; using addr_t = typename super::addr_t; - using ICmpInst = typename super::ICmpInst; + using tu_builder = typename super::tu_builder; vm_impl(); @@ -77,11 +77,10 @@ public: protected: using vm_base::get_reg_ptr; - using translation_unit = typename vm_base::translation_unit; using this_class = vm_impl; using compile_ret_t = std::tuple; - using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr, translation_unit&); + using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr, tu_builder&); inline const char *name(size_t index){return traits::reg_aliases.at(index);} @@ -89,34 +88,34 @@ protected: super::setup_module(m); } - compile_ret_t gen_single_inst_behavior(virt_addr_t &, unsigned int &, translation_unit&) override; + compile_ret_t gen_single_inst_behavior(virt_addr_t &, unsigned int &, tu_builder&) override; - void gen_trap_behavior(translation_unit& tu) override; + void gen_trap_behavior(tu_builder& tu) override; - void gen_raise_trap(translation_unit& tu, uint16_t trap_id, uint16_t cause); + void gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause); - void gen_leave_trap(translation_unit& tu, unsigned lvl); + void gen_leave_trap(tu_builder& tu, unsigned lvl); - void gen_wait(translation_unit& tu, unsigned type); + void gen_wait(tu_builder& tu, unsigned type); - inline void gen_trap_check(translation_unit& tu) { - tu<<" if(*trap_state!=0) goto trap_entry;"; + inline void gen_trap_check(tu_builder& tu) { + tu("if(*trap_state!=0) goto trap_entry;"); } - inline void gen_set_pc(translation_unit& tu, virt_addr_t pc, unsigned reg_num) { + inline void gen_set_pc(tu_builder& tu, virt_addr_t pc, unsigned reg_num) { switch(reg_num){ case traits::NEXT_PC: - tu(" *next_pc = {:#x};", pc.val); + tu("*next_pc = {:#x};", pc.val); break; case traits::PC: - tu(" *pc = {:#x};", pc.val); + tu("*pc = {:#x};", pc.val); break; default: if(!tu.defined_regs[reg_num]){ - tu(" reg_t* reg{:02d} = (reg_t*){:#x};", reg_num, reinterpret_cast(get_reg_ptr(reg_num))); + tu("reg_t* reg{:02d} = (reg_t*){:#x};", reg_num, reinterpret_cast(get_reg_ptr(reg_num))); tu.defined_regs[reg_num]=true; } - tu(" *reg{:02d} = {:#x};", reg_num, pc.val); + tu("*reg{:02d} = {:#x};", reg_num, pc.val); } } @@ -349,7 +348,7 @@ private: /* instruction definitions */ /* instruction 0: LUI */ - compile_ret_t __lui(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __lui(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("LUI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 0); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -359,14 +358,14 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.gen_const(32U, imm), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.gen_const(32U, imm), 32); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -377,7 +376,7 @@ private: } /* instruction 1: AUIPC */ - compile_ret_t __auipc(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __auipc(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("AUIPC_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 1); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -387,18 +386,18 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_add( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_add( tu.gen_ext( cur_pc_val, 32, true), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -409,7 +408,7 @@ private: } /* instruction 2: JAL */ - compile_ret_t __jal(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __jal(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("JAL_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 2); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -419,26 +418,26 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_add( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_add( cur_pc_val, tu.gen_const(32U, 4)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; - tu << tu.create_assignment("PC_val", tu.create_add( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_add( tu.gen_ext( cur_pc_val, 32, true), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_assignment("is_cont_v", tu.create_icmp(ICmpInst::ICMP_NE, "PC_val", tu.gen_const(32U, pc.val)), 1); - tu << tu.create_store("is_cont_v?1:0",traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + auto is_cont_v = tu.create_assignment("is_cont", tu.create_icmp(ICmpInst::ICMP_NE, PC_val_v, tu.create_zext_or_trunc(PC_val_v, 32U)), 1); + tu.create_store(is_cont_v, traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 2); @@ -447,7 +446,7 @@ private: } /* instruction 3: JALR */ - compile_ret_t __jalr(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __jalr(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("JALR_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 3); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -458,9 +457,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto new_pc_val = tu.create_add( @@ -470,17 +469,17 @@ private: tu.gen_const(32U, imm)); ; if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_add( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_add( cur_pc_val, tu.gen_const(32U, 4)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; - tu << tu.create_assignment("PC_val", tu.create_and( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_and( new_pc_val, tu.create_not(tu.gen_const(32U, 0x1))), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_store(tu.gen_const(32U, std::numeric_limits::max()), traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + tu.create_store(tu.gen_const(32U, std::numeric_limits::max()), traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 3); @@ -489,7 +488,7 @@ private: } /* instruction 4: BEQ */ - compile_ret_t __beq(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __beq(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("BEQ_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 4); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); @@ -500,12 +499,12 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); - tu << tu.create_assignment("PC_val", tu.create_choose( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_EQ, tu.create_load(rs1 + traits::X0, 0), @@ -518,9 +517,9 @@ private: tu.create_add( cur_pc_val, tu.gen_const(32U, 4))), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_assignment("is_cont_v", tu.create_icmp(ICmpInst::ICMP_NE, "PC_val", tu.gen_const(32U, pc.val)), 1); - tu << tu.create_store("is_cont_v?1:0",traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + auto is_cont_v = tu.create_assignment("is_cont", tu.create_icmp(ICmpInst::ICMP_NE, PC_val_v, tu.create_zext_or_trunc(PC_val_v, 32U)), 1); + tu.create_store(is_cont_v, traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 4); @@ -529,7 +528,7 @@ private: } /* instruction 5: BNE */ - compile_ret_t __bne(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __bne(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("BNE_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 5); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); @@ -540,12 +539,12 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); - tu << tu.create_assignment("PC_val", tu.create_choose( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_NE, tu.create_load(rs1 + traits::X0, 0), @@ -558,9 +557,9 @@ private: tu.create_add( cur_pc_val, tu.gen_const(32U, 4))), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_assignment("is_cont_v", tu.create_icmp(ICmpInst::ICMP_NE, "PC_val", tu.gen_const(32U, pc.val)), 1); - tu << tu.create_store("is_cont_v?1:0",traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + auto is_cont_v = tu.create_assignment("is_cont", tu.create_icmp(ICmpInst::ICMP_NE, PC_val_v, tu.create_zext_or_trunc(PC_val_v, 32U)), 1); + tu.create_store(is_cont_v, traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 5); @@ -569,7 +568,7 @@ private: } /* instruction 6: BLT */ - compile_ret_t __blt(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __blt(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("BLT_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 6); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); @@ -580,12 +579,12 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); - tu << tu.create_assignment("PC_val", tu.create_choose( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_SLT, tu.gen_ext( @@ -602,9 +601,9 @@ private: tu.create_add( cur_pc_val, tu.gen_const(32U, 4))), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_assignment("is_cont_v", tu.create_icmp(ICmpInst::ICMP_NE, "PC_val", tu.gen_const(32U, pc.val)), 1); - tu << tu.create_store("is_cont_v?1:0",traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + auto is_cont_v = tu.create_assignment("is_cont", tu.create_icmp(ICmpInst::ICMP_NE, PC_val_v, tu.create_zext_or_trunc(PC_val_v, 32U)), 1); + tu.create_store(is_cont_v, traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 6); @@ -613,7 +612,7 @@ private: } /* instruction 7: BGE */ - compile_ret_t __bge(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __bge(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("BGE_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 7); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); @@ -624,12 +623,12 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); - tu << tu.create_assignment("PC_val", tu.create_choose( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_SGE, tu.gen_ext( @@ -646,9 +645,9 @@ private: tu.create_add( cur_pc_val, tu.gen_const(32U, 4))), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_assignment("is_cont_v", tu.create_icmp(ICmpInst::ICMP_NE, "PC_val", tu.gen_const(32U, pc.val)), 1); - tu << tu.create_store("is_cont_v?1:0",traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + auto is_cont_v = tu.create_assignment("is_cont", tu.create_icmp(ICmpInst::ICMP_NE, PC_val_v, tu.create_zext_or_trunc(PC_val_v, 32U)), 1); + tu.create_store(is_cont_v, traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 7); @@ -657,7 +656,7 @@ private: } /* instruction 8: BLTU */ - compile_ret_t __bltu(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __bltu(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("BLTU_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 8); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); @@ -668,12 +667,12 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); - tu << tu.create_assignment("PC_val", tu.create_choose( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_ULT, tu.create_load(rs1 + traits::X0, 0), @@ -686,9 +685,9 @@ private: tu.create_add( cur_pc_val, tu.gen_const(32U, 4))), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_assignment("is_cont_v", tu.create_icmp(ICmpInst::ICMP_NE, "PC_val", tu.gen_const(32U, pc.val)), 1); - tu << tu.create_store("is_cont_v?1:0",traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + auto is_cont_v = tu.create_assignment("is_cont", tu.create_icmp(ICmpInst::ICMP_NE, PC_val_v, tu.create_zext_or_trunc(PC_val_v, 32U)), 1); + tu.create_store(is_cont_v, traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 8); @@ -697,7 +696,7 @@ private: } /* instruction 9: BGEU */ - compile_ret_t __bgeu(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __bgeu(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("BGEU_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 9); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); @@ -708,12 +707,12 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); - tu << tu.create_assignment("PC_val", tu.create_choose( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_UGE, tu.create_load(rs1 + traits::X0, 0), @@ -726,9 +725,9 @@ private: tu.create_add( cur_pc_val, tu.gen_const(32U, 4))), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_assignment("is_cont_v", tu.create_icmp(ICmpInst::ICMP_NE, "PC_val", tu.gen_const(32U, pc.val)), 1); - tu << tu.create_store("is_cont_v?1:0",traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + auto is_cont_v = tu.create_assignment("is_cont", tu.create_icmp(ICmpInst::ICMP_NE, PC_val_v, tu.create_zext_or_trunc(PC_val_v, 32U)), 1); + tu.create_store(is_cont_v, traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 9); @@ -737,7 +736,7 @@ private: } /* instruction 10: LB */ - compile_ret_t __lb(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __lb(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("LB_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 10); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -748,9 +747,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto offs_val = tu.create_add( @@ -760,11 +759,11 @@ private: tu.gen_const(32U, imm)); ; if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.gen_ext( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.gen_ext( tu.create_read_mem(traits::MEM, offs_val, 8/8), 32, true), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -775,7 +774,7 @@ private: } /* instruction 11: LH */ - compile_ret_t __lh(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __lh(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("LH_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 11); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -786,9 +785,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto offs_val = tu.create_add( @@ -798,11 +797,11 @@ private: tu.gen_const(32U, imm)); ; if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.gen_ext( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.gen_ext( tu.create_read_mem(traits::MEM, offs_val, 16/8), 32, true), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -813,7 +812,7 @@ private: } /* instruction 12: LW */ - compile_ret_t __lw(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __lw(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("LW_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 12); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -824,9 +823,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto offs_val = tu.create_add( @@ -836,11 +835,11 @@ private: tu.gen_const(32U, imm)); ; if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.gen_ext( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.gen_ext( tu.create_read_mem(traits::MEM, offs_val, 32/8), 32, true), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -851,7 +850,7 @@ private: } /* instruction 13: LBU */ - compile_ret_t __lbu(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __lbu(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("LBU_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 13); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -862,9 +861,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto offs_val = tu.create_add( @@ -874,11 +873,11 @@ private: tu.gen_const(32U, imm)); ; if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.gen_ext( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.gen_ext( tu.create_read_mem(traits::MEM, offs_val, 8/8), 32, false), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -889,7 +888,7 @@ private: } /* instruction 14: LHU */ - compile_ret_t __lhu(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __lhu(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("LHU_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 14); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -900,9 +899,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto offs_val = tu.create_add( @@ -912,11 +911,11 @@ private: tu.gen_const(32U, imm)); ; if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.gen_ext( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.gen_ext( tu.create_read_mem(traits::MEM, offs_val, 16/8), 32, false), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -927,7 +926,7 @@ private: } /* instruction 15: SB */ - compile_ret_t __sb(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __sb(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SB_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 15); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); @@ -938,9 +937,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto offs_val = tu.create_add( @@ -949,11 +948,11 @@ private: 32, true), tu.gen_const(32U, imm)); ; - tu << tu.create_assignment("MEMtmp0_val", tu.create_load(rs2 + traits::X0, 0), 8); - tu << tu.create_write_mem( + auto MEMtmp0_val_v = tu.create_assignment("MEMtmp0_val", tu.create_load(rs2 + traits::X0, 0), 8); + tu.create_write_mem( traits::MEM, offs_val, - "MEMtmp0_val", 8/8);; + MEMtmp0_val_v);; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); vm_base::gen_sync(tu, POST_SYNC, 15); @@ -962,7 +961,7 @@ private: } /* instruction 16: SH */ - compile_ret_t __sh(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __sh(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SH_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 16); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); @@ -973,9 +972,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto offs_val = tu.create_add( @@ -984,11 +983,11 @@ private: 32, true), tu.gen_const(32U, imm)); ; - tu << tu.create_assignment("MEMtmp0_val", tu.create_load(rs2 + traits::X0, 0), 16); - tu << tu.create_write_mem( + auto MEMtmp0_val_v = tu.create_assignment("MEMtmp0_val", tu.create_load(rs2 + traits::X0, 0), 16); + tu.create_write_mem( traits::MEM, offs_val, - "MEMtmp0_val", 16/8);; + MEMtmp0_val_v);; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); vm_base::gen_sync(tu, POST_SYNC, 16); @@ -997,7 +996,7 @@ private: } /* instruction 17: SW */ - compile_ret_t __sw(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __sw(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SW_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 17); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); @@ -1008,9 +1007,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto offs_val = tu.create_add( @@ -1019,11 +1018,11 @@ private: 32, true), tu.gen_const(32U, imm)); ; - tu << tu.create_assignment("MEMtmp0_val", tu.create_load(rs2 + traits::X0, 0), 32); - tu << tu.create_write_mem( + auto MEMtmp0_val_v = tu.create_assignment("MEMtmp0_val", tu.create_load(rs2 + traits::X0, 0), 32); + tu.create_write_mem( traits::MEM, offs_val, - "MEMtmp0_val", 32/8);; + MEMtmp0_val_v);; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); vm_base::gen_sync(tu, POST_SYNC, 17); @@ -1032,7 +1031,7 @@ private: } /* instruction 18: ADDI */ - compile_ret_t __addi(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __addi(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("ADDI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 18); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1043,18 +1042,18 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_add( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_add( tu.gen_ext( tu.create_load(rs1 + traits::X0, 0), 32, true), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1065,7 +1064,7 @@ private: } /* instruction 19: SLTI */ - compile_ret_t __slti(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __slti(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SLTI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 19); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1076,13 +1075,13 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_choose( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_SLT, tu.gen_ext( @@ -1091,7 +1090,7 @@ private: tu.gen_const(32U, imm)), tu.gen_const(32U, 1), tu.gen_const(32U, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1102,7 +1101,7 @@ private: } /* instruction 20: SLTIU */ - compile_ret_t __sltiu(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __sltiu(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SLTIU_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 20); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1113,22 +1112,22 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); int32_t full_imm_val = imm; ; if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_choose( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_ULT, tu.create_load(rs1 + traits::X0, 0), tu.gen_const(32U, full_imm_val)), tu.gen_const(32U, 1), tu.gen_const(32U, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1139,7 +1138,7 @@ private: } /* instruction 21: XORI */ - compile_ret_t __xori(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __xori(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("XORI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 21); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1150,18 +1149,18 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_xor( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_xor( tu.gen_ext( tu.create_load(rs1 + traits::X0, 0), 32, true), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1172,7 +1171,7 @@ private: } /* instruction 22: ORI */ - compile_ret_t __ori(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __ori(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("ORI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 22); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1183,18 +1182,18 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_or( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_or( tu.gen_ext( tu.create_load(rs1 + traits::X0, 0), 32, true), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1205,7 +1204,7 @@ private: } /* instruction 23: ANDI */ - compile_ret_t __andi(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __andi(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("ANDI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 23); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1216,18 +1215,18 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_and( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_and( tu.gen_ext( tu.create_load(rs1 + traits::X0, 0), 32, true), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1238,7 +1237,7 @@ private: } /* instruction 24: SLLI */ - compile_ret_t __slli(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __slli(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SLLI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 24); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1249,19 +1248,19 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(shamt > 31){ this->gen_raise_trap(tu, 0, 0); } else { if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_shl( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_shl( tu.create_load(rs1 + traits::X0, 0), tu.gen_const(32U, shamt)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } } ; @@ -1273,7 +1272,7 @@ private: } /* instruction 25: SRLI */ - compile_ret_t __srli(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __srli(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SRLI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 25); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1284,19 +1283,19 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(shamt > 31){ this->gen_raise_trap(tu, 0, 0); } else { if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_lshr( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_lshr( tu.create_load(rs1 + traits::X0, 0), tu.gen_const(32U, shamt)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } } ; @@ -1308,7 +1307,7 @@ private: } /* instruction 26: SRAI */ - compile_ret_t __srai(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __srai(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SRAI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 26); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1319,19 +1318,19 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(shamt > 31){ this->gen_raise_trap(tu, 0, 0); } else { if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_ashr( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_ashr( tu.create_load(rs1 + traits::X0, 0), tu.gen_const(32U, shamt)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } } ; @@ -1343,7 +1342,7 @@ private: } /* instruction 27: ADD */ - compile_ret_t __add(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __add(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("ADD_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 27); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1354,16 +1353,16 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_add( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_add( tu.create_load(rs1 + traits::X0, 0), tu.create_load(rs2 + traits::X0, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1374,7 +1373,7 @@ private: } /* instruction 28: SUB */ - compile_ret_t __sub(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __sub(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SUB_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 28); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1385,16 +1384,16 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_sub( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_sub( tu.create_load(rs1 + traits::X0, 0), tu.create_load(rs2 + traits::X0, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1405,7 +1404,7 @@ private: } /* instruction 29: SLL */ - compile_ret_t __sll(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __sll(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SLL_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 29); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1416,20 +1415,20 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_shl( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_shl( tu.create_load(rs1 + traits::X0, 0), tu.create_and( tu.create_load(rs2 + traits::X0, 0), tu.create_sub( tu.gen_const(32U, 32), tu.gen_const(32U, 1)))), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1440,7 +1439,7 @@ private: } /* instruction 30: SLT */ - compile_ret_t __slt(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __slt(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SLT_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 30); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1451,13 +1450,13 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_choose( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_SLT, tu.gen_ext( @@ -1468,7 +1467,7 @@ private: 32, true)), tu.gen_const(32U, 1), tu.gen_const(32U, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1479,7 +1478,7 @@ private: } /* instruction 31: SLTU */ - compile_ret_t __sltu(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __sltu(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SLTU_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 31); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1490,13 +1489,13 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_choose( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_ULT, tu.gen_ext( @@ -1509,7 +1508,7 @@ private: false)), tu.gen_const(32U, 1), tu.gen_const(32U, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1520,7 +1519,7 @@ private: } /* instruction 32: XOR */ - compile_ret_t __xor(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __xor(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("XOR_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 32); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1531,16 +1530,16 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_xor( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_xor( tu.create_load(rs1 + traits::X0, 0), tu.create_load(rs2 + traits::X0, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1551,7 +1550,7 @@ private: } /* instruction 33: SRL */ - compile_ret_t __srl(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __srl(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SRL_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 33); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1562,20 +1561,20 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_lshr( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_lshr( tu.create_load(rs1 + traits::X0, 0), tu.create_and( tu.create_load(rs2 + traits::X0, 0), tu.create_sub( tu.gen_const(32U, 32), tu.gen_const(32U, 1)))), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1586,7 +1585,7 @@ private: } /* instruction 34: SRA */ - compile_ret_t __sra(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __sra(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SRA_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 34); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1597,20 +1596,20 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_ashr( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_ashr( tu.create_load(rs1 + traits::X0, 0), tu.create_and( tu.create_load(rs2 + traits::X0, 0), tu.create_sub( tu.gen_const(32U, 32), tu.gen_const(32U, 1)))), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1621,7 +1620,7 @@ private: } /* instruction 35: OR */ - compile_ret_t __or(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __or(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("OR_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 35); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1632,16 +1631,16 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_or( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_or( tu.create_load(rs1 + traits::X0, 0), tu.create_load(rs2 + traits::X0, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1652,7 +1651,7 @@ private: } /* instruction 36: AND */ - compile_ret_t __and(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __and(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("AND_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 36); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1663,16 +1662,16 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_and( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_and( tu.create_load(rs1 + traits::X0, 0), tu.create_load(rs2 + traits::X0, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -1683,7 +1682,7 @@ private: } /* instruction 37: FENCE */ - compile_ret_t __fence(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __fence(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("FENCE_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 37); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1692,20 +1691,20 @@ private: uint8_t pred = ((bit_sub<24,4>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "fence"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "fence"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); - tu << tu.create_assignment("FENCEtmp0_val", tu.create_or( + auto FENCEtmp0_val_v = tu.create_assignment("FENCEtmp0_val", tu.create_or( tu.create_shl( tu.gen_const(32U, pred), tu.gen_const(32U, 4)), tu.gen_const(32U, succ)), 32); - tu << tu.create_write_mem( + tu.create_write_mem( traits::FENCE, tu.gen_const(64U, 0), - "FENCEtmp0_val", 32/8);; + FENCEtmp0_val_v);; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); vm_base::gen_sync(tu, POST_SYNC, 37); @@ -1714,7 +1713,7 @@ private: } /* instruction 38: FENCE_I */ - compile_ret_t __fence_i(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __fence_i(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("FENCE_I_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 38); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1722,18 +1721,18 @@ private: uint16_t imm = ((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "fence_i"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "fence_i"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); - tu << tu.create_assignment("FENCEtmp0_val", tu.gen_const(32U, imm), 32); - tu << tu.create_write_mem( + auto FENCEtmp0_val_v = tu.create_assignment("FENCEtmp0_val", tu.gen_const(32U, imm), 32); + tu.create_write_mem( traits::FENCE, tu.gen_const(64U, 1), - "FENCEtmp0_val", 32/8);; + FENCEtmp0_val_v);; tu.close_scope(); - tu(" *last_branch={}", std::numeric_limits::max()); + tu.create_store(tu.gen_const(32, std::numeric_limits::max()),traits::LAST_BRANCH); gen_set_pc(tu, pc, traits::NEXT_PC); vm_base::gen_sync(tu, POST_SYNC, 38); gen_trap_check(tu); @@ -1741,14 +1740,14 @@ private: } /* instruction 39: ECALL */ - compile_ret_t __ecall(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __ecall(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("ECALL_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 39); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "ecall"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "ecall"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); this->gen_raise_trap(tu, 0, 11);; @@ -1759,14 +1758,14 @@ private: } /* instruction 40: EBREAK */ - compile_ret_t __ebreak(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __ebreak(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("EBREAK_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 40); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "ebreak"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "ebreak"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); this->gen_raise_trap(tu, 0, 3);; @@ -1777,14 +1776,14 @@ private: } /* instruction 41: URET */ - compile_ret_t __uret(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __uret(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("URET_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 41); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "uret"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "uret"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); this->gen_leave_trap(tu, 0);; @@ -1795,14 +1794,14 @@ private: } /* instruction 42: SRET */ - compile_ret_t __sret(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __sret(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SRET_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 42); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "sret"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "sret"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); this->gen_leave_trap(tu, 1);; @@ -1813,14 +1812,14 @@ private: } /* instruction 43: MRET */ - compile_ret_t __mret(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __mret(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("MRET_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 43); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "mret"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "mret"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); this->gen_leave_trap(tu, 3);; @@ -1831,14 +1830,14 @@ private: } /* instruction 44: WFI */ - compile_ret_t __wfi(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __wfi(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("WFI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 44); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "wfi"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "wfi"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); this->gen_wait(tu, 1);; @@ -1850,28 +1849,28 @@ private: } /* instruction 45: SFENCE.VMA */ - compile_ret_t __sfence_vma(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __sfence_vma(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("SFENCE_VMA_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 45); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "sfence.vma"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "sfence.vma"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); - tu << tu.create_assignment("FENCEtmp0_val", tu.gen_const(32U, rs1), 32); - tu << tu.create_write_mem( + auto FENCEtmp0_val_v = tu.create_assignment("FENCEtmp0_val", tu.gen_const(32U, rs1), 32); + tu.create_write_mem( traits::FENCE, tu.gen_const(64U, 2), - "FENCEtmp0_val", 32/8);; - tu << tu.create_assignment("FENCEtmp1_val", tu.gen_const(32U, rs2), 32); - tu << tu.create_write_mem( + FENCEtmp0_val_v);; + auto FENCEtmp1_val_v = tu.create_assignment("FENCEtmp1_val", tu.gen_const(32U, rs2), 32); + tu.create_write_mem( traits::FENCE, tu.gen_const(64U, 3), - "FENCEtmp1_val", 32/8);; + FENCEtmp1_val_v);; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); vm_base::gen_sync(tu, POST_SYNC, 45); @@ -1880,7 +1879,7 @@ private: } /* instruction 46: CSRRW */ - compile_ret_t __csrrw(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __csrrw(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("CSRRW_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 46); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1891,28 +1890,28 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto rs_val_val = tu.create_load(rs1 + traits::X0, 0); ; if(rd != 0){ auto csr_val_val = tu.create_read_mem(traits::CSR, tu.gen_const(16U, csr), 32/8); - tu << tu.create_assignment("CSRtmp0_val", rs_val_val, 32); - tu << tu.create_write_mem( + auto CSRtmp0_val_v = tu.create_assignment("CSRtmp0_val", rs_val_val, 32); + tu.create_write_mem( traits::CSR, tu.gen_const(16U, csr), - "CSRtmp0_val", 32/8); - tu << tu.create_assignment("Xtmp1_val", csr_val_val, 32); - tu << tu.create_store("Xtmp1_val", rd + traits::X0); + CSRtmp0_val_v); + auto Xtmp1_val_v = tu.create_assignment("Xtmp1_val", csr_val_val, 32); + tu.create_store(Xtmp1_val_v, rd + traits::X0); } else { - tu << tu.create_assignment("CSRtmp2_val", rs_val_val, 32); - tu << tu.create_write_mem( + auto CSRtmp2_val_v = tu.create_assignment("CSRtmp2_val", rs_val_val, 32); + tu.create_write_mem( traits::CSR, tu.gen_const(16U, csr), - "CSRtmp2_val", 32/8); + CSRtmp2_val_v); } ; tu.close_scope(); @@ -1923,7 +1922,7 @@ private: } /* instruction 47: CSRRS */ - compile_ret_t __csrrs(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __csrrs(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("CSRRS_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 47); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1934,9 +1933,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto xrd_val = tu.create_read_mem(traits::CSR, tu.gen_const(16U, csr), 32/8); @@ -1944,18 +1943,18 @@ private: auto xrs1_val = tu.create_load(rs1 + traits::X0, 0); ; if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", xrd_val, 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", xrd_val, 32); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; if(rs1 != 0){ - tu << tu.create_assignment("CSRtmp1_val", tu.create_or( + auto CSRtmp1_val_v = tu.create_assignment("CSRtmp1_val", tu.create_or( xrd_val, xrs1_val), 32); - tu << tu.create_write_mem( + tu.create_write_mem( traits::CSR, tu.gen_const(16U, csr), - "CSRtmp1_val", 32/8); + CSRtmp1_val_v); } ; tu.close_scope(); @@ -1966,7 +1965,7 @@ private: } /* instruction 48: CSRRC */ - compile_ret_t __csrrc(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __csrrc(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("CSRRC_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 48); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1977,9 +1976,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto xrd_val = tu.create_read_mem(traits::CSR, tu.gen_const(16U, csr), 32/8); @@ -1987,18 +1986,18 @@ private: auto xrs1_val = tu.create_load(rs1 + traits::X0, 0); ; if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", xrd_val, 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", xrd_val, 32); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; if(rs1 != 0){ - tu << tu.create_assignment("CSRtmp1_val", tu.create_and( + auto CSRtmp1_val_v = tu.create_assignment("CSRtmp1_val", tu.create_and( xrd_val, tu.create_not(xrs1_val)), 32); - tu << tu.create_write_mem( + tu.create_write_mem( traits::CSR, tu.gen_const(16U, csr), - "CSRtmp1_val", 32/8); + CSRtmp1_val_v); } ; tu.close_scope(); @@ -2009,7 +2008,7 @@ private: } /* instruction 49: CSRRWI */ - compile_ret_t __csrrwi(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __csrrwi(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("CSRRWI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 49); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -2020,24 +2019,24 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", tu.create_read_mem(traits::CSR, tu.gen_const(16U, csr), 32/8), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_read_mem(traits::CSR, tu.gen_const(16U, csr), 32/8), 32); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; - tu << tu.create_assignment("CSRtmp1_val", tu.gen_ext( + auto CSRtmp1_val_v = tu.create_assignment("CSRtmp1_val", tu.gen_ext( tu.gen_const(32U, zimm), 32, false), 32); - tu << tu.create_write_mem( + tu.create_write_mem( traits::CSR, tu.gen_const(16U, csr), - "CSRtmp1_val", 32/8);; + CSRtmp1_val_v);; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); vm_base::gen_sync(tu, POST_SYNC, 49); @@ -2046,7 +2045,7 @@ private: } /* instruction 50: CSRRSI */ - compile_ret_t __csrrsi(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __csrrsi(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("CSRRSI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 50); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -2057,29 +2056,29 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto res_val = tu.create_read_mem(traits::CSR, tu.gen_const(16U, csr), 32/8); ; if(zimm != 0){ - tu << tu.create_assignment("CSRtmp0_val", tu.create_or( + auto CSRtmp0_val_v = tu.create_assignment("CSRtmp0_val", tu.create_or( res_val, tu.gen_ext( tu.gen_const(32U, zimm), 32, false)), 32); - tu << tu.create_write_mem( + tu.create_write_mem( traits::CSR, tu.gen_const(16U, csr), - "CSRtmp0_val", 32/8); + CSRtmp0_val_v); } ; if(rd != 0){ - tu << tu.create_assignment("Xtmp1_val", res_val, 32); - tu << tu.create_store("Xtmp1_val", rd + traits::X0); + auto Xtmp1_val_v = tu.create_assignment("Xtmp1_val", res_val, 32); + tu.create_store(Xtmp1_val_v, rd + traits::X0); } ; tu.close_scope(); @@ -2090,7 +2089,7 @@ private: } /* instruction 51: CSRRCI */ - compile_ret_t __csrrci(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __csrrci(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("CSRRCI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 51); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -2101,29 +2100,29 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+4; tu.open_scope(); auto res_val = tu.create_read_mem(traits::CSR, tu.gen_const(16U, csr), 32/8); ; if(rd != 0){ - tu << tu.create_assignment("Xtmp0_val", res_val, 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", res_val, 32); + tu.create_store(Xtmp0_val_v, rd + traits::X0); } ; if(zimm != 0){ - tu << tu.create_assignment("CSRtmp1_val", tu.create_and( + auto CSRtmp1_val_v = tu.create_assignment("CSRtmp1_val", tu.create_and( res_val, tu.create_not(tu.gen_ext( tu.gen_const(32U, zimm), 32, false))), 32); - tu << tu.create_write_mem( + tu.create_write_mem( traits::CSR, tu.gen_const(16U, csr), - "CSRtmp1_val", 32/8); + CSRtmp1_val_v); } ; tu.close_scope(); @@ -2134,7 +2133,7 @@ private: } /* instruction 52: C.ADDI4SPN */ - compile_ret_t __c_addi4spn(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_addi4spn(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_ADDI4SPN_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 52); uint8_t rd = ((bit_sub<2,3>(instr))); @@ -2144,19 +2143,19 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.addi4spn"), fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); if(imm == 0){ this->gen_raise_trap(tu, 0, 2); } ; - tu << tu.create_assignment("Xtmp0_val", tu.create_add( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_add( tu.create_load(2 + traits::X0, 0), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("Xtmp0_val", rd + 8 + traits::X0); + tu.create_store(Xtmp0_val_v, rd + 8 + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2166,7 +2165,7 @@ private: } /* instruction 53: C.LW */ - compile_ret_t __c_lw(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_lw(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_LW_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 53); uint8_t rd = ((bit_sub<2,3>(instr))); @@ -2177,20 +2176,20 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.lw"), fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); auto offs_val = tu.create_add( tu.create_load(rs1 + 8 + traits::X0, 0), tu.gen_const(32U, uimm)); ; - tu << tu.create_assignment("Xtmp0_val", tu.gen_ext( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.gen_ext( tu.create_read_mem(traits::MEM, offs_val, 32/8), 32, true), 32); - tu << tu.create_store("Xtmp0_val", rd + 8 + traits::X0); + tu.create_store(Xtmp0_val_v, rd + 8 + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2200,7 +2199,7 @@ private: } /* instruction 54: C.SW */ - compile_ret_t __c_sw(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_sw(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_SW_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 54); uint8_t rs2 = ((bit_sub<2,3>(instr))); @@ -2211,20 +2210,20 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs2}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.sw"), fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); auto offs_val = tu.create_add( tu.create_load(rs1 + 8 + traits::X0, 0), tu.gen_const(32U, uimm)); ; - tu << tu.create_assignment("MEMtmp0_val", tu.create_load(rs2 + 8 + traits::X0, 0), 32); - tu << tu.create_write_mem( + auto MEMtmp0_val_v = tu.create_assignment("MEMtmp0_val", tu.create_load(rs2 + 8 + traits::X0, 0), 32); + tu.create_write_mem( traits::MEM, offs_val, - "MEMtmp0_val", 32/8);; + MEMtmp0_val_v);; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); vm_base::gen_sync(tu, POST_SYNC, 54); @@ -2233,7 +2232,7 @@ private: } /* instruction 55: C.ADDI */ - compile_ret_t __c_addi(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_addi(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_ADDI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 55); int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); @@ -2243,17 +2242,17 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addi"), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); - tu << tu.create_assignment("Xtmp0_val", tu.create_add( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_add( tu.gen_ext( tu.create_load(rs1 + traits::X0, 0), 32, true), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("Xtmp0_val", rs1 + traits::X0); + tu.create_store(Xtmp0_val_v, rs1 + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2263,14 +2262,14 @@ private: } /* instruction 56: C.NOP */ - compile_ret_t __c_nop(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_nop(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_NOP_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 56); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "c.nop"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "c.nop"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); tu.close_scope(); @@ -2282,7 +2281,7 @@ private: } /* instruction 57: C.JAL */ - compile_ret_t __c_jal(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_jal(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_JAL_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 57); int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11)); @@ -2291,24 +2290,24 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.jal"), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); - tu << tu.create_assignment("Xtmp0_val", tu.create_add( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_add( cur_pc_val, tu.gen_const(32U, 2)), 32); - tu << tu.create_store("Xtmp0_val", 1 + traits::X0); + tu.create_store(Xtmp0_val_v, 1 + traits::X0); ; - tu << tu.create_assignment("PC_val", tu.create_add( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_add( tu.gen_ext( cur_pc_val, 32, true), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_assignment("is_cont_v", tu.create_icmp(ICmpInst::ICMP_NE, "PC_val", tu.gen_const(32U, pc.val)), 1); - tu << tu.create_store("is_cont_v?1:0",traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + auto is_cont_v = tu.create_assignment("is_cont", tu.create_icmp(ICmpInst::ICMP_NE, PC_val_v, tu.create_zext_or_trunc(PC_val_v, 32U)), 1); + tu.create_store(is_cont_v, traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 57); @@ -2317,7 +2316,7 @@ private: } /* instruction 58: C.LI */ - compile_ret_t __c_li(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_li(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_LI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 58); int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); @@ -2327,17 +2326,17 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.li"), fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); if(rd == 0){ this->gen_raise_trap(tu, 0, 2); } ; - tu << tu.create_assignment("Xtmp0_val", tu.gen_const(32U, imm), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.gen_const(32U, imm), 32); + tu.create_store(Xtmp0_val_v, rd + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2347,7 +2346,7 @@ private: } /* instruction 59: C.LUI */ - compile_ret_t __c_lui(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_lui(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_LUI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 59); int32_t imm = signextend((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); @@ -2357,9 +2356,9 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.lui"), fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); if(rd == 0){ @@ -2370,8 +2369,8 @@ private: this->gen_raise_trap(tu, 0, 2); } ; - tu << tu.create_assignment("Xtmp0_val", tu.gen_const(32U, imm), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.gen_const(32U, imm), 32); + tu.create_store(Xtmp0_val_v, rd + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2381,7 +2380,7 @@ private: } /* instruction 60: C.ADDI16SP */ - compile_ret_t __c_addi16sp(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_addi16sp(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_ADDI16SP_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 60); int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); @@ -2390,17 +2389,17 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.addi16sp"), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); - tu << tu.create_assignment("Xtmp0_val", tu.create_add( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_add( tu.gen_ext( tu.create_load(2 + traits::X0, 0), 32, true), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("Xtmp0_val", 2 + traits::X0); + tu.create_store(Xtmp0_val_v, 2 + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2410,7 +2409,7 @@ private: } /* instruction 61: C.SRLI */ - compile_ret_t __c_srli(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_srli(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_SRLI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 61); uint8_t shamt = ((bit_sub<2,5>(instr))); @@ -2420,17 +2419,17 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srli"), fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); uint8_t rs1_idx_val = rs1 + 8; ; - tu << tu.create_assignment("Xtmp0_val", tu.create_lshr( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_lshr( tu.create_load(rs1_idx_val + traits::X0, 0), tu.gen_const(32U, shamt)), 32); - tu << tu.create_store("Xtmp0_val", rs1_idx_val + traits::X0); + tu.create_store(Xtmp0_val_v, rs1_idx_val + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2440,7 +2439,7 @@ private: } /* instruction 62: C.SRAI */ - compile_ret_t __c_srai(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_srai(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_SRAI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 62); uint8_t shamt = ((bit_sub<2,5>(instr))); @@ -2450,17 +2449,17 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srai"), fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); uint8_t rs1_idx_val = rs1 + 8; ; - tu << tu.create_assignment("Xtmp0_val", tu.create_ashr( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_ashr( tu.create_load(rs1_idx_val + traits::X0, 0), tu.gen_const(32U, shamt)), 32); - tu << tu.create_store("Xtmp0_val", rs1_idx_val + traits::X0); + tu.create_store(Xtmp0_val_v, rs1_idx_val + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2470,7 +2469,7 @@ private: } /* instruction 63: C.ANDI */ - compile_ret_t __c_andi(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_andi(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_ANDI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 63); int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); @@ -2480,19 +2479,19 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.andi"), fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); uint8_t rs1_idx_val = rs1 + 8; ; - tu << tu.create_assignment("Xtmp0_val", tu.create_and( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_and( tu.gen_ext( tu.create_load(rs1_idx_val + traits::X0, 0), 32, true), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("Xtmp0_val", rs1_idx_val + traits::X0); + tu.create_store(Xtmp0_val_v, rs1_idx_val + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2502,7 +2501,7 @@ private: } /* instruction 64: C.SUB */ - compile_ret_t __c_sub(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_sub(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_SUB_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 64); uint8_t rs2 = ((bit_sub<2,3>(instr))); @@ -2512,17 +2511,17 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.sub"), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); uint8_t rd_idx_val = rd + 8; ; - tu << tu.create_assignment("Xtmp0_val", tu.create_sub( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_sub( tu.create_load(rd_idx_val + traits::X0, 0), tu.create_load(rs2 + 8 + traits::X0, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd_idx_val + traits::X0); + tu.create_store(Xtmp0_val_v, rd_idx_val + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2532,7 +2531,7 @@ private: } /* instruction 65: C.XOR */ - compile_ret_t __c_xor(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_xor(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_XOR_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 65); uint8_t rs2 = ((bit_sub<2,3>(instr))); @@ -2542,17 +2541,17 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.xor"), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); uint8_t rd_idx_val = rd + 8; ; - tu << tu.create_assignment("Xtmp0_val", tu.create_xor( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_xor( tu.create_load(rd_idx_val + traits::X0, 0), tu.create_load(rs2 + 8 + traits::X0, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd_idx_val + traits::X0); + tu.create_store(Xtmp0_val_v, rd_idx_val + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2562,7 +2561,7 @@ private: } /* instruction 66: C.OR */ - compile_ret_t __c_or(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_or(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_OR_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 66); uint8_t rs2 = ((bit_sub<2,3>(instr))); @@ -2572,17 +2571,17 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.or"), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); uint8_t rd_idx_val = rd + 8; ; - tu << tu.create_assignment("Xtmp0_val", tu.create_or( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_or( tu.create_load(rd_idx_val + traits::X0, 0), tu.create_load(rs2 + 8 + traits::X0, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd_idx_val + traits::X0); + tu.create_store(Xtmp0_val_v, rd_idx_val + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2592,7 +2591,7 @@ private: } /* instruction 67: C.AND */ - compile_ret_t __c_and(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_and(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_AND_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 67); uint8_t rs2 = ((bit_sub<2,3>(instr))); @@ -2602,17 +2601,17 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.and"), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); uint8_t rd_idx_val = rd + 8; ; - tu << tu.create_assignment("Xtmp0_val", tu.create_and( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_and( tu.create_load(rd_idx_val + traits::X0, 0), tu.create_load(rs2 + 8 + traits::X0, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd_idx_val + traits::X0); + tu.create_store(Xtmp0_val_v, rd_idx_val + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2622,7 +2621,7 @@ private: } /* instruction 68: C.J */ - compile_ret_t __c_j(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_j(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_J_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 68); int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11)); @@ -2631,19 +2630,19 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.j"), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); - tu << tu.create_assignment("PC_val", tu.create_add( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_add( tu.gen_ext( cur_pc_val, 32, true), tu.gen_const(32U, imm)), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_assignment("is_cont_v", tu.create_icmp(ICmpInst::ICMP_NE, "PC_val", tu.gen_const(32U, pc.val)), 1); - tu << tu.create_store("is_cont_v?1:0",traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + auto is_cont_v = tu.create_assignment("is_cont", tu.create_icmp(ICmpInst::ICMP_NE, PC_val_v, tu.create_zext_or_trunc(PC_val_v, 32U)), 1); + tu.create_store(is_cont_v, traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 68); @@ -2652,7 +2651,7 @@ private: } /* instruction 69: C.BEQZ */ - compile_ret_t __c_beqz(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_beqz(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_BEQZ_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 69); int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); @@ -2662,12 +2661,12 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.beqz"), fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); - tu << tu.create_assignment("PC_val", tu.create_choose( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_EQ, tu.create_load(rs1 + 8 + traits::X0, 0), @@ -2680,9 +2679,9 @@ private: tu.create_add( cur_pc_val, tu.gen_const(32U, 2))), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_assignment("is_cont_v", tu.create_icmp(ICmpInst::ICMP_NE, "PC_val", tu.gen_const(32U, pc.val)), 1); - tu << tu.create_store("is_cont_v?1:0",traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + auto is_cont_v = tu.create_assignment("is_cont", tu.create_icmp(ICmpInst::ICMP_NE, PC_val_v, tu.create_zext_or_trunc(PC_val_v, 32U)), 1); + tu.create_store(is_cont_v, traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 69); @@ -2691,7 +2690,7 @@ private: } /* instruction 70: C.BNEZ */ - compile_ret_t __c_bnez(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_bnez(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_BNEZ_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 70); int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); @@ -2701,12 +2700,12 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.bnez"), fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); - tu << tu.create_assignment("PC_val", tu.create_choose( + auto PC_val_v = tu.create_assignment("PC_val", tu.create_choose( tu.create_icmp( ICmpInst::ICMP_NE, tu.create_load(rs1 + 8 + traits::X0, 0), @@ -2719,9 +2718,9 @@ private: tu.create_add( cur_pc_val, tu.gen_const(32U, 2))), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_assignment("is_cont_v", tu.create_icmp(ICmpInst::ICMP_NE, "PC_val", tu.gen_const(32U, pc.val)), 1); - tu << tu.create_store("is_cont_v?1:0",traits::LAST_BRANCH); + tu.create_store(PC_val_v, traits::NEXT_PC); + auto is_cont_v = tu.create_assignment("is_cont", tu.create_icmp(ICmpInst::ICMP_NE, PC_val_v, tu.create_zext_or_trunc(PC_val_v, 32U)), 1); + tu.create_store(is_cont_v, traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 70); @@ -2730,7 +2729,7 @@ private: } /* instruction 71: C.SLLI */ - compile_ret_t __c_slli(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_slli(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_SLLI_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 71); uint8_t shamt = ((bit_sub<2,5>(instr))); @@ -2740,19 +2739,19 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.slli"), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); if(rs1 == 0){ this->gen_raise_trap(tu, 0, 2); } ; - tu << tu.create_assignment("Xtmp0_val", tu.create_shl( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_shl( tu.create_load(rs1 + traits::X0, 0), tu.gen_const(32U, shamt)), 32); - tu << tu.create_store("Xtmp0_val", rs1 + traits::X0); + tu.create_store(Xtmp0_val_v, rs1 + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2762,7 +2761,7 @@ private: } /* instruction 72: C.LWSP */ - compile_ret_t __c_lwsp(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_lwsp(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_LWSP_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 72); uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); @@ -2772,20 +2771,20 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "c.lwsp"), fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); auto offs_val = tu.create_add( tu.create_load(2 + traits::X0, 0), tu.gen_const(32U, uimm)); ; - tu << tu.create_assignment("Xtmp0_val", tu.gen_ext( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.gen_ext( tu.create_read_mem(traits::MEM, offs_val, 32/8), 32, true), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2795,7 +2794,7 @@ private: } /* instruction 73: C.MV */ - compile_ret_t __c_mv(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_mv(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_MV_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 73); uint8_t rs2 = ((bit_sub<2,5>(instr))); @@ -2805,13 +2804,13 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.mv"), fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); - tu << tu.create_assignment("Xtmp0_val", tu.create_load(rs2 + traits::X0, 0), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_load(rs2 + traits::X0, 0), 32); + tu.create_store(Xtmp0_val_v, rd + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2821,7 +2820,7 @@ private: } /* instruction 74: C.JR */ - compile_ret_t __c_jr(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_jr(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_JR_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 74); uint8_t rs1 = ((bit_sub<7,5>(instr))); @@ -2830,14 +2829,14 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jr"), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); - tu << tu.create_assignment("PC_val", tu.create_load(rs1 + traits::X0, 0), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_store(tu.gen_const(32U, std::numeric_limits::max()), traits::LAST_BRANCH); + auto PC_val_v = tu.create_assignment("PC_val", tu.create_load(rs1 + traits::X0, 0), 32); + tu.create_store(PC_val_v, traits::NEXT_PC); + tu.create_store(tu.gen_const(32U, std::numeric_limits::max()), traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 74); @@ -2846,7 +2845,7 @@ private: } /* instruction 75: C.ADD */ - compile_ret_t __c_add(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_add(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_ADD_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 75); uint8_t rs2 = ((bit_sub<2,5>(instr))); @@ -2856,15 +2855,15 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.add"), fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); - tu << tu.create_assignment("Xtmp0_val", tu.create_add( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_add( tu.create_load(rd + traits::X0, 0), tu.create_load(rs2 + traits::X0, 0)), 32); - tu << tu.create_store("Xtmp0_val", rd + traits::X0); + tu.create_store(Xtmp0_val_v, rd + traits::X0); ; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); @@ -2874,7 +2873,7 @@ private: } /* instruction 76: C.JALR */ - compile_ret_t __c_jalr(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_jalr(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_JALR_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 76); uint8_t rs1 = ((bit_sub<7,5>(instr))); @@ -2883,19 +2882,19 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jalr"), fmt::arg("rs1", name(rs1))); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); - tu << tu.create_assignment("Xtmp0_val", tu.create_add( + auto Xtmp0_val_v = tu.create_assignment("Xtmp0_val", tu.create_add( cur_pc_val, tu.gen_const(32U, 2)), 32); - tu << tu.create_store("Xtmp0_val", 1 + traits::X0); + tu.create_store(Xtmp0_val_v, 1 + traits::X0); ; - tu << tu.create_assignment("PC_val", tu.create_load(rs1 + traits::X0, 0), 32); - tu << tu.create_store("PC_val", traits::NEXT_PC); - tu << tu.create_store(tu.gen_const(32U, std::numeric_limits::max()), traits::LAST_BRANCH); + auto PC_val_v = tu.create_assignment("PC_val", tu.create_load(rs1 + traits::X0, 0), 32); + tu.create_store(PC_val_v, traits::NEXT_PC); + tu.create_store(tu.gen_const(32U, std::numeric_limits::max()), traits::LAST_BRANCH); ; tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 76); @@ -2904,14 +2903,14 @@ private: } /* instruction 77: C.EBREAK */ - compile_ret_t __c_ebreak(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_ebreak(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_EBREAK_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 77); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "c.ebreak"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "c.ebreak"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); this->gen_raise_trap(tu, 0, 3);; @@ -2922,7 +2921,7 @@ private: } /* instruction 78: C.SWSP */ - compile_ret_t __c_swsp(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __c_swsp(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("C_SWSP_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 78); uint8_t rs2 = ((bit_sub<2,5>(instr))); @@ -2932,20 +2931,20 @@ private: auto mnemonic = fmt::format( "{mnemonic:10} {rs2}, {uimm:#05x}(sp)", fmt::arg("mnemonic", "c.swsp"), fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); auto offs_val = tu.create_add( tu.create_load(2 + traits::X0, 0), tu.gen_const(32U, uimm)); ; - tu << tu.create_assignment("MEMtmp0_val", tu.create_load(rs2 + traits::X0, 0), 32); - tu << tu.create_write_mem( + auto MEMtmp0_val_v = tu.create_assignment("MEMtmp0_val", tu.create_load(rs2 + traits::X0, 0), 32); + tu.create_write_mem( traits::MEM, offs_val, - "MEMtmp0_val", 32/8);; + MEMtmp0_val_v);; tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); vm_base::gen_sync(tu, POST_SYNC, 78); @@ -2954,14 +2953,14 @@ private: } /* instruction 79: DII */ - compile_ret_t __dii(virt_addr_t& pc, code_word_t instr, translation_unit& tu){ + compile_ret_t __dii(virt_addr_t& pc, code_word_t instr, tu_builder& tu){ tu("DII_{:#010x}:", pc.val); vm_base::gen_sync(tu, PRE_SYNC, 79); if(this->disass_enabled){ /* generate console output when executing the command */ - tu(" print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "dii"); + tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, "dii"); } - auto cur_pc_val = fmt::format("{}", pc.val); + auto cur_pc_val = tu.gen_const(arch::traits::reg_bit_widths[traits::PC], pc.val); pc=pc+2; tu.open_scope(); this->gen_raise_trap(tu, 0, 2);; @@ -2974,7 +2973,7 @@ private: /**************************************************************************** * end opcode definitions ****************************************************************************/ - compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr, translation_unit& tu) { + compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr, tu_builder& tu) { vm_impl::gen_sync(tu, iss::PRE_SYNC, instr_descr.size()); pc = pc + ((instr & 3) == 3 ? 4 : 2); gen_raise_trap(tu, 0, 2); // illegal instruction trap @@ -3006,7 +3005,7 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) template std::tuple -vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, translation_unit& tu) { +vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, tu_builder& tu) { // we fetch at max 4 byte, alignment is 2 enum {TRAP_ID=1<<16}; code_word_t insn = 0; @@ -3035,24 +3034,25 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, return (this->*f)(pc, insn, tu); } -template void vm_impl::gen_raise_trap(translation_unit& tu, uint16_t trap_id, uint16_t cause) { +template void vm_impl::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) { tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id); - tu << tu.create_store(tu.gen_const(32, std::numeric_limits::max()),traits::LAST_BRANCH); + tu.create_store(tu.gen_const(32, std::numeric_limits::max()),traits::LAST_BRANCH); } -template void vm_impl::gen_leave_trap(translation_unit& tu, unsigned lvl) { - tu(" leave_trap(core_ptr, {});", lvl); - tu(" *next_pc = {};", tu.create_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8)); - tu << tu.create_store(tu.gen_const(32, std::numeric_limits::max()),traits::LAST_BRANCH); +template void vm_impl::gen_leave_trap(tu_builder& tu, unsigned lvl) { + tu("leave_trap(core_ptr, {});", lvl); + tu.create_store(tu.create_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8),traits::NEXT_PC); + tu.create_store(tu.gen_const(32, std::numeric_limits::max()),traits::LAST_BRANCH); } -template void vm_impl::gen_wait(translation_unit& tu, unsigned type) { +template void vm_impl::gen_wait(tu_builder& tu, unsigned type) { } -template void vm_impl::gen_trap_behavior(translation_unit& tu) { - tu<<"trap_entry:"; - tu(" enter_trap(core_ptr, *trap_state, *pc);"); - tu(" return *next_pc;"); +template void vm_impl::gen_trap_behavior(tu_builder& tu) { + tu("trap_entry:"); + tu("enter_trap(core_ptr, *trap_state, *pc);"); + tu.create_store(tu.gen_const(32, std::numeric_limits::max()),traits::LAST_BRANCH); + tu("return *next_pc;"); } } // namespace mnrv32