updates LLVM build
This commit is contained in:
@@ -253,6 +253,7 @@ private:
|
||||
//static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK;
|
||||
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
|
||||
auto phys_pc = this->core.v2p(pc);
|
||||
//TODO: re-add page handling
|
||||
//if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
|
||||
// if (this->core.read(phys_pc, 2, data) != iss::Ok) return iss::Err;
|
||||
// if ((data[0] & 0x3) == 0x3) // this is a 32bit instruction
|
||||
|
@@ -111,7 +111,7 @@ protected:
|
||||
void gen_trap_check(BasicBlock *bb);
|
||||
|
||||
inline Value *gen_reg_load(unsigned i, unsigned level = 0) {
|
||||
return this->builder.CreateLoad(get_reg_ptr(i), false);
|
||||
return this->builder.CreateLoad(this->get_typeptr(i), get_reg_ptr(i), false);
|
||||
}
|
||||
|
||||
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
|
||||
@@ -124,7 +124,7 @@ protected:
|
||||
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
||||
enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
|
||||
enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 };
|
||||
enum { LUT_SIZE = 1 << util::bit_count(EXTR_MASK32), LUT_SIZE_C = 1 << util::bit_count(EXTR_MASK16) };
|
||||
enum { LUT_SIZE = 1 << util::bit_count(static_cast<uint64_t>(EXTR_MASK32)), LUT_SIZE_C = 1 << util::bit_count(static_cast<uint64_t>(EXTR_MASK16)) };
|
||||
|
||||
using this_class = vm_impl<ARCH>;
|
||||
using compile_func = std::tuple<continuation_e, BasicBlock *> (this_class::*)(virt_addr_t &pc,
|
||||
@@ -4042,10 +4042,10 @@ private:
|
||||
****************************************************************************/
|
||||
std::tuple<continuation_e, BasicBlock *> illegal_intruction(virt_addr_t &pc, code_word_t instr, BasicBlock *bb) {
|
||||
this->gen_sync(iss::PRE_SYNC, instr_descr.size());
|
||||
this->builder.CreateStore(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), true),
|
||||
this->builder.CreateStore(this->builder.CreateLoad(this->get_typeptr(traits<ARCH>::NEXT_PC), get_reg_ptr(traits<ARCH>::NEXT_PC), true),
|
||||
get_reg_ptr(traits<ARCH>::PC), true);
|
||||
this->builder.CreateStore(
|
||||
this->builder.CreateAdd(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::ICOUNT), true),
|
||||
this->builder.CreateAdd(this->builder.CreateLoad(this->get_typeptr(traits<ARCH>::ICOUNT), get_reg_ptr(traits<ARCH>::ICOUNT), true),
|
||||
this->gen_const(64U, 1)),
|
||||
get_reg_ptr(traits<ARCH>::ICOUNT), true);
|
||||
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
||||
@@ -4082,20 +4082,21 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||
// 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;
|
||||
// const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK;
|
||||
phys_addr_t paddr(pc);
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
//TODO: re-add page handling
|
||||
// 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);
|
||||
// }
|
||||
// } 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
|
||||
++inst_cnt;
|
||||
@@ -4109,7 +4110,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||
|
||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_behavior(BasicBlock *leave_blk) {
|
||||
this->builder.SetInsertPoint(leave_blk);
|
||||
this->builder.CreateRet(this->builder.CreateLoad(get_reg_ptr(arch::traits<ARCH>::NEXT_PC), false));
|
||||
this->builder.CreateRet(this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::NEXT_PC), get_reg_ptr(arch::traits<ARCH>::NEXT_PC), false));
|
||||
}
|
||||
|
||||
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) {
|
||||
@@ -4133,18 +4134,18 @@ template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
|
||||
|
||||
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
|
||||
this->builder.SetInsertPoint(trap_blk);
|
||||
auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
||||
auto *trap_state_val = this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::TRAP_STATE), get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
||||
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
|
||||
get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
||||
std::vector<Value *> args{this->core_ptr, this->adj_to64(trap_state_val),
|
||||
this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))};
|
||||
this->adj_to64(this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::PC), get_reg_ptr(traits<ARCH>::PC), false))};
|
||||
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
|
||||
auto *trap_addr_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
||||
auto *trap_addr_val = this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::NEXT_PC), get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
||||
this->builder.CreateRet(trap_addr_val);
|
||||
}
|
||||
|
||||
template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(BasicBlock *bb) {
|
||||
auto *v = this->builder.CreateLoad(get_reg_ptr(arch::traits<ARCH>::TRAP_STATE), true);
|
||||
auto *v = this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::TRAP_STATE), get_reg_ptr(arch::traits<ARCH>::TRAP_STATE), true);
|
||||
this->gen_cond_branch(this->builder.CreateICmp(
|
||||
ICmpInst::ICMP_EQ, v,
|
||||
ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))),
|
||||
@@ -4161,3 +4162,25 @@ std::unique_ptr<vm_if> create<arch::tgc_c>(arch::tgc_c *core, unsigned short por
|
||||
}
|
||||
} // namespace llvm
|
||||
} // namespace iss
|
||||
|
||||
#include <iss/factory.h>
|
||||
#include <iss/arch/riscv_hart_m_p.h>
|
||||
#include <iss/arch/riscv_hart_mu_p.h>
|
||||
namespace iss {
|
||||
namespace {
|
||||
volatile std::array<bool, 2> dummy = {
|
||||
core_factory::instance().register_creator("tgc_c|m_p|llvm", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::tgc_c>();
|
||||
auto* vm = new llvm::tgc_c::vm_impl<arch::tgc_c>(*cpu, false);
|
||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||
}),
|
||||
core_factory::instance().register_creator("tgc_c|mu_p|llvm", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::tgc_c>();
|
||||
auto* vm = new llvm::tgc_c::vm_impl<arch::tgc_c>(*cpu, false);
|
||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -3168,6 +3168,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||
phys_addr_t paddr(pc);
|
||||
auto *const data = (uint8_t *)&insn;
|
||||
paddr = this->core.v2p(pc);
|
||||
//TODO: re-add page handling
|
||||
// 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);
|
||||
|
Reference in New Issue
Block a user