[WIP] add next increment for TCC

This commit is contained in:
2020-04-17 19:23:43 +02:00
parent ae1c0b99fe
commit 264053a8d6
6 changed files with 517 additions and 509 deletions

View File

@ -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<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
@ -204,7 +206,7 @@ protected:
std::array<address_type, 4> addr_mode;
bool interrupt_sim=false;
uint64_t interrupt_sim=0;
<%
def fcsr = allRegs.find {it.name=='FCSR'}
if(fcsr != null) {%>

View File

@ -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<ARCH>::get_reg_ptr;
using translation_unit = typename vm_base<ARCH>::translation_unit;
using this_class = vm_impl<ARCH>;
using compile_ret_t = std::tuple<continuation_e>;
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<ARCH>::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<ARCH>::NEXT_PC:
tu(" *next_pc = {:#x};", pc.val);
tu("*next_pc = {:#x};", pc.val);
break;
case traits<ARCH>::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<uintptr_t>(get_reg_ptr(reg_num)));
tu("reg_t* reg{:02d} = (reg_t*){:#x};", reg_num, reinterpret_cast<uintptr_t>(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<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
template <typename ARCH>
std::tuple<continuation_e>
vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, translation_unit& tu) {
vm_impl<ARCH>::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<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
return (this->*f)(pc, insn, tu);
}
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(translation_unit& tu, uint16_t trap_id, uint16_t cause) {
template <typename ARCH> void vm_impl<ARCH>::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<uint32_t>::max()),traits<ARCH>::LAST_BRANCH);
tu.create_store(tu.gen_const(32, std::numeric_limits<uint32_t>::max()),traits<ARCH>::LAST_BRANCH);
}
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(translation_unit& tu, unsigned lvl) {
tu(" leave_trap(core_ptr, {});", lvl);
tu(" *next_pc = {};", tu.create_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8));
tu << tu.create_store(tu.gen_const(32, std::numeric_limits<uint32_t>::max()),traits<ARCH>::LAST_BRANCH);
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
tu("leave_trap(core_ptr, {});", lvl);
tu.create_store(tu.create_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8),traits<ARCH>::NEXT_PC);
tu.create_store(tu.gen_const(32, std::numeric_limits<uint32_t>::max()),traits<ARCH>::LAST_BRANCH);
}
template <typename ARCH> void vm_impl<ARCH>::gen_wait(translation_unit& tu, unsigned type) {
template <typename ARCH> void vm_impl<ARCH>::gen_wait(tu_builder& tu, unsigned type) {
}
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(translation_unit& tu) {
tu<<"trap_entry:";
tu(" enter_trap(core_ptr, *trap_state, *pc);");
tu(" return *next_pc;");
template <typename ARCH> void vm_impl<ARCH>::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<uint32_t>::max()),traits<ARCH>::LAST_BRANCH);
tu("return *next_pc;");
}
} // namespace mnrv32