[WIP] integrate tcc conan package

This commit is contained in:
Eyck Jentzsch 2020-04-10 17:14:04 +02:00
parent 15f4c059e6
commit 50663a2fbc
5 changed files with 79 additions and 30 deletions

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.3) cmake_minimum_required(VERSION 3.12)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) # main (top) cmake dir set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) # main (top) cmake dir
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # project specific cmake dir set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # project specific cmake dir
@ -66,7 +66,7 @@ set(LIBRARY_NAME riscv)
# Define the library # Define the library
add_library(${LIBRARY_NAME} ${LIB_SOURCES}) add_library(${LIBRARY_NAME} ${LIB_SOURCES})
SET(${LIBRARY_NAME} -Wl,-whole-archive -l${LIBRARY_NAME} -Wl,-no-whole-archive) SET(${LIBRARY_NAME} -Wl,-whole-archive -l${LIBRARY_NAME} -Wl,-no-whole-archive)
target_link_libraries(${LIBRARY_NAME} softfloat dbt-core tinycc scc-util) target_link_libraries(${LIBRARY_NAME} softfloat dbt-core scc-util)
set_target_properties(${LIBRARY_NAME} PROPERTIES set_target_properties(${LIBRARY_NAME} PROPERTIES
VERSION ${VERSION} # ${VERSION} was defined in the main CMakeLists. VERSION ${VERSION} # ${VERSION} was defined in the main CMakeLists.
FRAMEWORK FALSE FRAMEWORK FALSE

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.3) cmake_minimum_required(VERSION 3.12)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) # main (top) cmake dir set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) # main (top) cmake dir
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # project specific cmake dir set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # project specific cmake dir

View File

@ -57,11 +57,11 @@ namespace rv64i {
using namespace iss::arch; using namespace iss::arch;
using namespace llvm; using namespace llvm;
using namespace iss::debugger; using namespace iss::debugger;
using namespace iss::vm::llvm; using namespace iss::llvm;
template <typename ARCH> class vm_impl : public vm_base<ARCH> { template <typename ARCH> class vm_impl : public vm_base<ARCH> {
public: public:
using super = typename iss::vm::llvm::vm_base<ARCH>; using super = typename iss::llvm::vm_base<ARCH>;
using virt_addr_t = typename super::virt_addr_t; using virt_addr_t = typename super::virt_addr_t;
using phys_addr_t = typename super::phys_addr_t; using phys_addr_t = typename super::phys_addr_t;
using code_word_t = typename super::code_word_t; using code_word_t = typename super::code_word_t;

View File

@ -111,16 +111,16 @@ protected:
void gen_trap_behavior(std::ostringstream& os) override; void gen_trap_behavior(std::ostringstream& os) override;
void gen_trap_check(std::ostringstream& os){} void gen_trap_check(std::ostringstream& os){
os<< fmt::format("if(*(uint32_t){})!=0) goto trap_blk;\n", get_reg_ptr(arch::traits<ARCH>::TRAP_STATE));
}
inline Value *gen_reg_load(unsigned i, unsigned level = 0) { inline Value *gen_reg_load(unsigned i, unsigned level = 0) {
return this->builder.CreateLoad(get_reg_ptr(i), false); return this->builder.CreateLoad(get_reg_ptr(i), false);
} }
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { inline void gen_set_pc(std::ostringstream& os, virt_addr_t pc, unsigned reg_num) {
Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val), os<< fmt::format("*((uint64_t*){}) = {}\n", get_reg_ptr(reg_num), pc.val);
this->get_type(traits<ARCH>::XLEN));
this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
} }
// some compile time constants // some compile time constants
@ -301,11 +301,36 @@ private:
/* instruction 1: AUIPC */ /* instruction 1: AUIPC */
compile_ret_t __auipc(virt_addr_t& pc, code_word_t instr, std::ostringstream& os){ compile_ret_t __auipc(virt_addr_t& pc, code_word_t instr, std::ostringstream& os){
os<<fmt::format("AUIPC-{:%08x}:\n", pc.val);
this->gen_sync(os, PRE_SYNC, 1);
uint8_t rd = ((bit_sub<7,5>(instr)));
int32_t imm = signextend<int32_t,32>((bit_sub<12,20>(instr) << 12));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"),
fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
os<<fmt::format("\tprint_disass((void*){}, {}, {});\n", this->core_ptr, pc.val, mnemonic);
}
Value* cur_pc_val = this->gen_const(64, pc.val);
pc=pc+4;
if(rd != 0){
os<<fmt::format("uint64_t res = {} + {};\n", cur_pc_val, imm);
os<<fmt::format("*((uint64_t*){}) = ret\n", get_reg_ptr(rd + traits<ARCH>::X0));
}
this->gen_set_pc(os, pc, traits<ARCH>::NEXT_PC);
this->gen_sync(os, POST_SYNC, 1);
this->gen_trap_check(os);
return std::make_tuple(CONT);
} }
/* instruction 2: JAL */ /* instruction 2: JAL */
compile_ret_t __jal(virt_addr_t& pc, code_word_t instr, std::ostringstream& os){ compile_ret_t __jal(virt_addr_t& pc, code_word_t instr, std::ostringstream& os){
this->gen_sync(PRE_SYNC, 0); this->gen_sync(os, PRE_SYNC, 0);
uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr)));
@ -320,6 +345,9 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
pc=pc+4; pc=pc+4;
} }
/* instruction 3: JALR */ /* instruction 3: JALR */
@ -521,12 +549,12 @@ private:
/**************************************************************************** /****************************************************************************
* end opcode definitions * end opcode definitions
****************************************************************************/ ****************************************************************************/
compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr, std::ostringstream& oss) { compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr, std::ostringstream& os) {
vm_impl::gen_sync(iss::PRE_SYNC, instr_descr.size()); this->gen_sync(os, iss::PRE_SYNC, instr_descr.size());
pc = pc + ((instr & 3) == 3 ? 4 : 2); pc = pc + ((instr & 3) == 3 ? 4 : 2);
gen_raise_trap(0, 2); // illegal instruction trap gen_raise_trap(0, 2); // illegal instruction trap
vm_impl::gen_sync(iss::POST_SYNC, instr_descr.size()); this->gen_sync(os, iss::POST_SYNC, instr_descr.size());
vm_impl::gen_trap_check(oss); this->gen_trap_check(os);
return BRANCH; return BRANCH;
} }
}; };

View File

@ -35,7 +35,7 @@
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
#include <iss/iss.h> #include <iss/iss.h>
#include <iss/llvm/vm_base.h> #include <iss/tcc/vm_base.h>
#include <util/logging.h> #include <util/logging.h>
#ifndef FMT_HEADER_ONLY #ifndef FMT_HEADER_ONLY
@ -57,11 +57,10 @@ namespace tcc {
namespace rv64i { namespace rv64i {
using namespace iss::arch; using namespace iss::arch;
using namespace iss::debugger; using namespace iss::debugger;
using namespace iss::vm::llvm;
template <typename ARCH> class vm_impl : public vm_base<ARCH> { template <typename ARCH> class vm_impl : public vm_base<ARCH> {
public: public:
using super = typename iss::vm::llvm::vm_base<ARCH>; using super = typename iss::tcc::vm_base<ARCH>;
using virt_addr_t = typename super::virt_addr_t; using virt_addr_t = typename super::virt_addr_t;
using phys_addr_t = typename super::phys_addr_t; using phys_addr_t = typename super::phys_addr_t;
using code_word_t = typename super::code_word_t; using code_word_t = typename super::code_word_t;
@ -114,16 +113,14 @@ protected:
void gen_trap_behavior(BasicBlock *) override; void gen_trap_behavior(BasicBlock *) override;
void gen_trap_check(BasicBlock *bb); std::string gen_trap_check(BasicBlock *bb);
inline Value *gen_reg_load(unsigned i, unsigned level = 0) { inline Value *gen_reg_load(unsigned i, unsigned level = 0) {
return this->builder.CreateLoad(get_reg_ptr(i), false); return this->builder.CreateLoad(get_reg_ptr(i), false);
} }
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { inline std::string gen_set_pc(virt_addr_t pc, unsigned reg_num) {
Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val), return fmt::format("*((uint64_t*){}) = {}\n", get_reg_ptr(reg_num), next_pc_v.val);
this->get_type(traits<ARCH>::XLEN));
this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
} }
// some compile time constants // some compile time constants
@ -328,6 +325,33 @@ private:
/* instruction 1: AUIPC */ /* instruction 1: AUIPC */
compile_ret_t __auipc(virt_addr_t& pc, code_word_t instr, std::ostringstream& os){ compile_ret_t __auipc(virt_addr_t& pc, code_word_t instr, std::ostringstream& os){
os<<fmt::format("AUIPC-{:%08x}:\n", pc.val);
os<<this->gen_sync(PRE_SYNC, 1);
uint8_t rd = ((bit_sub<7,5>(instr)));
int32_t imm = signextend<int32_t,32>((bit_sub<12,20>(instr) << 12));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"),
fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
os<<fmt::format("\tprint_disass((void*){}, {}, {});\n", this->core_ptr, pc.val, mnemonic);
}
Value* cur_pc_val = this->gen_const(64, pc.val);
pc=pc+4;
if(rd != 0){
os<<fmt::format("uint64_t res = {} + {};\n", cur_pc_val, imm);
os<<fmt::format("*((uint64_t*){}) = ret\n", get_reg_ptr(rd + traits<ARCH>::X0));
}
os<<this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
os<<this->gen_sync(POST_SYNC, 1);
os<<this->gen_trap_check(bb);
return std::make_tuple(CONT);
} }
/* instruction 2: JAL */ /* instruction 2: JAL */
@ -684,12 +708,9 @@ template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_
this->builder.CreateRet(trap_addr_val); this->builder.CreateRet(trap_addr_val);
} }
template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(BasicBlock *bb) { template <typename ARCH> inline std::string vm_impl<ARCH>::gen_trap_check(BasicBlock *bb) {
auto *v = this->builder.CreateLoad(get_reg_ptr(arch::traits<ARCH>::TRAP_STATE), true); return fmt::format("if(*(uint32_t){})!=0) goto trap_blk;\n", get_reg_ptr(arch::traits<ARCH>::TRAP_STATE));
this->gen_cond_branch(this->builder.CreateICmp(
ICmpInst::ICMP_EQ, v,
ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))),
bb, this->trap_blk, 1);
} }
} // namespace rv64i } // namespace rv64i