Fixed implementation of RV64 so that remaining riscv-test pass
This commit is contained in:
		| @@ -29,7 +29,45 @@ | ||||
|  * POSSIBILITY OF SUCH DAMAGE. | ||||
|  * | ||||
|  *******************************************************************************/ | ||||
|  | ||||
|  <%  | ||||
| import com.minres.coredsl.coreDsl.Register | ||||
| import com.minres.coredsl.coreDsl.RegisterFile | ||||
| import com.minres.coredsl.coreDsl.RegisterAlias | ||||
| def getOriginalName(reg){ | ||||
|     if( reg.original instanceof RegisterFile) { | ||||
|     	if( reg.index != null ) { | ||||
|         	return reg.original.name+generator.generateHostCode(reg.index) | ||||
|         } else { | ||||
|         	return reg.original.name | ||||
|         } | ||||
|     } else if(reg.original instanceof Register){ | ||||
|         return reg.original.name | ||||
|     } | ||||
| } | ||||
| def getRegisterNames(){ | ||||
| 	def regNames = [] | ||||
|  	allRegs.each { reg ->  | ||||
| 		if( reg instanceof RegisterFile) { | ||||
| 			(reg.range.right..reg.range.left).each{ | ||||
|     			regNames+=reg.name.toLowerCase()+it | ||||
|             } | ||||
|         } else if(reg instanceof Register){ | ||||
|     		regNames+=reg.name.toLowerCase() | ||||
|         } | ||||
|     } | ||||
|     return regNames | ||||
| } | ||||
| def getRegisterAliasNames(){ | ||||
| 	def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]} | ||||
|  	return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg -> | ||||
| 		if( reg instanceof RegisterFile) { | ||||
| 			return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() } | ||||
|         } else if(reg instanceof Register){ | ||||
|     		regMap[reg.name]?:reg.name.toLowerCase() | ||||
|         } | ||||
|  	}.flatten() | ||||
| } | ||||
| %> | ||||
| #include "util/ities.h" | ||||
| #include <util/logging.h> | ||||
|  | ||||
| @@ -49,27 +87,29 @@ extern "C" { | ||||
|  | ||||
| using namespace iss::arch; | ||||
|  | ||||
| constexpr std::array<const uint32_t, 39> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_sizes; | ||||
| constexpr std::array<const uint32_t, 40> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_byte_offset; | ||||
| constexpr std::array<const char*, ${getRegisterNames().size}>    iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_names; | ||||
| constexpr std::array<const char*, ${getRegisterAliasNames().size}>    iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_aliases; | ||||
| constexpr std::array<const uint32_t, ${regSizes.size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_bit_widths; | ||||
| constexpr std::array<const uint32_t, ${regOffsets.size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_byte_offsets; | ||||
|  | ||||
| ${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() { | ||||
|     reg.icount = 0; | ||||
|     reg.machine_state = 0x3; | ||||
| } | ||||
|  | ||||
| ${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}() = default; | ||||
| } | ||||
|  | ||||
| void ${coreDef.name.toLowerCase()}::reset(uint64_t address) { | ||||
|     for(size_t i=0; i<traits<${coreDef.name.toLowerCase()}>::NUM_REGS; ++i) | ||||
|     	set_reg(i, std::vector<uint8_t>(sizeof(traits<${coreDef.name.toLowerCase()}>::reg_t),0)); | ||||
|     for(size_t i=0; i<traits<${coreDef.name.toLowerCase()}>::NUM_REGS; ++i) set_reg(i, std::vector<uint8_t>(sizeof(traits<${coreDef.name.toLowerCase()}>::reg_t),0)); | ||||
|     reg.PC=address; | ||||
|     reg.NEXT_PC=reg.PC; | ||||
|     reg.trap_state=0; | ||||
|     reg.machine_state=0x3; | ||||
|     reg.machine_state=0x0; | ||||
|     reg.icount=0; | ||||
| } | ||||
|  | ||||
| uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() { return reinterpret_cast<uint8_t*>(®); } | ||||
| uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() { | ||||
| 	return reinterpret_cast<uint8_t*>(®); | ||||
| } | ||||
|  | ||||
| ${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &pc) { | ||||
|     return phys_addr_t(pc); // change logical address to physical address | ||||
|   | ||||
| @@ -46,7 +46,7 @@ | ||||
| namespace iss { | ||||
| namespace vm { | ||||
| namespace fp_impl { | ||||
| void add_fp_functions_2_module(llvm::Module *, unsigned); | ||||
| void add_fp_functions_2_module(llvm::Module *, unsigned, unsigned); | ||||
| } | ||||
| } | ||||
|  | ||||
| @@ -88,7 +88,7 @@ protected: | ||||
|  | ||||
|     void setup_module(Module* m) override { | ||||
|         super::setup_module(m); | ||||
|         iss::vm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE); | ||||
|         iss::vm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE, traits<ARCH>::XLEN); | ||||
|     } | ||||
|  | ||||
|     inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) { | ||||
| @@ -241,24 +241,21 @@ template <typename ARCH> | ||||
| std::tuple<continuation_e, BasicBlock *> | ||||
| vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, BasicBlock *this_block) { | ||||
|     // we fetch at max 4 byte, alignment is 2 | ||||
|     enum {TRAP_ID=1<<16}; | ||||
|     code_word_t insn = 0; | ||||
|     const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK; | ||||
|     phys_addr_t paddr(pc); | ||||
|     try { | ||||
|         auto *const data = (uint8_t *)&insn; | ||||
|         paddr = this->core.v2p(pc); | ||||
|         if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary | ||||
|             auto res = this->core.read(paddr, 2, data); | ||||
|             if (res != iss::Ok) throw trap_access(1, pc.val); | ||||
|             if ((insn & 0x3) == 0x3) { // this is a 32bit instruction | ||||
|                 res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); | ||||
|             } | ||||
|         } else { | ||||
|             auto res = this->core.read(paddr, 4, data); | ||||
|             if (res != iss::Ok) throw trap_access(1, pc.val); | ||||
|     auto *const data = (uint8_t *)&insn; | ||||
|     paddr = this->core.v2p(pc); | ||||
|     if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary | ||||
|         auto res = this->core.read(paddr, 2, data); | ||||
|         if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); | ||||
|         if ((insn & 0x3) == 0x3) { // this is a 32bit instruction | ||||
|             res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); | ||||
|         } | ||||
|     } catch (trap_access &ta) { | ||||
|         throw trap_access(ta.id, pc.val); | ||||
|     } else { | ||||
|         auto res = this->core.read(paddr, 4, data); | ||||
|         if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); | ||||
|     } | ||||
|     if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' | ||||
|     // curr pc on stack | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 eyck
					eyck