removes decoder again as there is some issue
This commit is contained in:
parent
18f33b4a68
commit
feaa49d367
|
@ -37,7 +37,6 @@ FILE(GLOB GEN_SOURCES
|
||||||
set(LIB_SOURCES
|
set(LIB_SOURCES
|
||||||
src/iss/plugin/instruction_count.cpp
|
src/iss/plugin/instruction_count.cpp
|
||||||
src/iss/arch/tgc_c.cpp
|
src/iss/arch/tgc_c.cpp
|
||||||
src/iss/arch/tgc_c_decoder.cpp
|
|
||||||
src/vm/interp/vm_tgc_c.cpp
|
src/vm/interp/vm_tgc_c.cpp
|
||||||
src/vm/fp_functions.cpp
|
src/vm/fp_functions.cpp
|
||||||
${GEN_SOURCES}
|
${GEN_SOURCES}
|
||||||
|
|
|
@ -69,7 +69,6 @@ def getCString(def val){
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iss/arch/traits.h>
|
#include <iss/arch/traits.h>
|
||||||
#include <iss/arch_if.h>
|
#include <iss/arch_if.h>
|
||||||
#include <iss/arch/instruction_decoder.h>
|
|
||||||
#include <iss/vm_if.h>
|
#include <iss/vm_if.h>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
|
@ -121,8 +120,6 @@ template <> struct traits<${coreDef.name.toLowerCase()}> {
|
||||||
${instr.instruction.name} = ${index},<%}%>
|
${instr.instruction.name} = ${index},<%}%>
|
||||||
MAX_OPCODE
|
MAX_OPCODE
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::unique_ptr<instruction_decoder<${coreDef.name.toLowerCase()}>> get_decoder();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ${coreDef.name.toLowerCase()}: public arch_if {
|
struct ${coreDef.name.toLowerCase()}: public arch_if {
|
||||||
|
|
|
@ -95,6 +95,7 @@ protected:
|
||||||
|
|
||||||
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
||||||
|
|
||||||
|
typename arch::traits<ARCH>::opcode_e decode_inst_id(code_word_t instr);
|
||||||
virt_addr_t execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit) override;
|
virt_addr_t execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit) override;
|
||||||
|
|
||||||
// some compile time constants
|
// some compile time constants
|
||||||
|
@ -111,7 +112,13 @@ protected:
|
||||||
std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
|
std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
|
||||||
std::array<compile_func, LUT_SIZE> lut_11;
|
std::array<compile_func, LUT_SIZE> lut_11;
|
||||||
|
|
||||||
std::unique_ptr<instruction_decoder<ARCH>> decoder;
|
struct instruction_pattern {
|
||||||
|
uint32_t value;
|
||||||
|
uint32_t mask;
|
||||||
|
typename arch::traits<ARCH>::opcode_e id;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::array<std::vector<instruction_pattern>, 4> qlut;
|
||||||
|
|
||||||
inline void raise(uint16_t trap_id, uint16_t cause){
|
inline void raise(uint16_t trap_id, uint16_t cause){
|
||||||
auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id;
|
auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id;
|
||||||
|
@ -133,7 +140,42 @@ protected:
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& pc_assign(T& val){super::ex_info.branch_taken=true; return val;}
|
T& pc_assign(T& val){super::ex_info.branch_taken=true; return val;}
|
||||||
|
inline uint8_t readSpace1(typename super::mem_type_e space, uint64_t addr){
|
||||||
|
auto ret = super::template read_mem<uint8_t>(space, addr);
|
||||||
|
if(this->core.trap_state) throw 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
inline uint16_t readSpace2(typename super::mem_type_e space, uint64_t addr){
|
||||||
|
auto ret = super::template read_mem<uint16_t>(space, addr);
|
||||||
|
if(this->core.trap_state) throw 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
inline uint32_t readSpace4(typename super::mem_type_e space, uint64_t addr){
|
||||||
|
auto ret = super::template read_mem<uint32_t>(space, addr);
|
||||||
|
if(this->core.trap_state) throw 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
inline uint64_t readSpace8(typename super::mem_type_e space, uint64_t addr){
|
||||||
|
auto ret = super::template read_mem<uint64_t>(space, addr);
|
||||||
|
if(this->core.trap_state) throw 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
inline void writeSpace1(typename super::mem_type_e space, uint64_t addr, uint8_t data){
|
||||||
|
super::write_mem(space, addr, data);
|
||||||
|
if(this->core.trap_state) throw 0;
|
||||||
|
}
|
||||||
|
inline void writeSpace2(typename super::mem_type_e space, uint64_t addr, uint16_t data){
|
||||||
|
super::write_mem(space, addr, data);
|
||||||
|
if(this->core.trap_state) throw 0;
|
||||||
|
}
|
||||||
|
inline void writeSpace4(typename super::mem_type_e space, uint64_t addr, uint32_t data){
|
||||||
|
super::write_mem(space, addr, data);
|
||||||
|
if(this->core.trap_state) throw 0;
|
||||||
|
}
|
||||||
|
inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){
|
||||||
|
super::write_mem(space, addr, data);
|
||||||
|
if(this->core.trap_state) throw 0;
|
||||||
|
}
|
||||||
template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
|
template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
|
||||||
inline S sext(U from) {
|
inline S sext(U from) {
|
||||||
auto mask = (1ULL<<W) - 1;
|
auto mask = (1ULL<<W) - 1;
|
||||||
|
@ -153,6 +195,20 @@ protected:
|
||||||
${it}<%}%>
|
${it}<%}%>
|
||||||
<%}%>
|
<%}%>
|
||||||
private:
|
private:
|
||||||
|
/****************************************************************************
|
||||||
|
* start opcode definitions
|
||||||
|
****************************************************************************/
|
||||||
|
struct InstructionDesriptor {
|
||||||
|
size_t length;
|
||||||
|
uint32_t value;
|
||||||
|
uint32_t mask;
|
||||||
|
typename arch::traits<ARCH>::opcode_e op;
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array<InstructionDesriptor, ${instructions.size}> instr_descr = {{
|
||||||
|
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
||||||
|
{${instr.length}, ${instr.encoding}, ${instr.mask}, arch::traits<ARCH>::opcode_e::${instr.instruction.name}},<%}%>
|
||||||
|
}};
|
||||||
|
|
||||||
//static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK;
|
//static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK;
|
||||||
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
|
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
|
||||||
|
@ -192,7 +248,16 @@ constexpr size_t bit_count(uint32_t u) {
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
||||||
: vm_base<ARCH>(core, core_id, cluster_id) {
|
: vm_base<ARCH>(core, core_id, cluster_id) {
|
||||||
decoder = traits::get_decoder();
|
unsigned id=0;
|
||||||
|
for (auto instr : instr_descr) {
|
||||||
|
auto quadrant = instr.value & 0x3;
|
||||||
|
qlut[quadrant].push_back(instruction_pattern{instr.value, instr.mask, instr.op});
|
||||||
|
}
|
||||||
|
for(auto& lut: qlut){
|
||||||
|
std::sort(std::begin(lut), std::end(lut), [](instruction_pattern const& a, instruction_pattern const& b){
|
||||||
|
return bit_count(a.mask) > bit_count(b.mask);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_count_limit_enabled(finish_cond_e cond){
|
inline bool is_count_limit_enabled(finish_cond_e cond){
|
||||||
|
@ -203,11 +268,19 @@ inline bool is_jump_to_self_enabled(finish_cond_e cond){
|
||||||
return (cond & finish_cond_e::JUMP_TO_SELF) == finish_cond_e::JUMP_TO_SELF;
|
return (cond & finish_cond_e::JUMP_TO_SELF) == finish_cond_e::JUMP_TO_SELF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ARCH>
|
||||||
|
typename arch::traits<ARCH>::opcode_e vm_impl<ARCH>::decode_inst_id(code_word_t instr){
|
||||||
|
for(auto& e: qlut[instr&0x3]){
|
||||||
|
if(!((instr&e.mask) ^ e.value )) return e.id;
|
||||||
|
}
|
||||||
|
return arch::traits<ARCH>::opcode_e::MAX_OPCODE;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){
|
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){
|
||||||
auto pc=start;
|
auto pc=start;
|
||||||
auto* PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+traits::reg_byte_offsets[traits::PC]);
|
auto* PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
|
||||||
auto* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+traits::reg_byte_offsets[traits::NEXT_PC]);
|
auto* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]);
|
||||||
auto& trap_state = this->core.trap_state;
|
auto& trap_state = this->core.trap_state;
|
||||||
auto& icount = this->core.icount;
|
auto& icount = this->core.icount;
|
||||||
auto& cycle = this->core.cycle;
|
auto& cycle = this->core.cycle;
|
||||||
|
@ -224,11 +297,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
} else {
|
} else {
|
||||||
if (is_jump_to_self_enabled(cond) &&
|
if (is_jump_to_self_enabled(cond) &&
|
||||||
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||||
auto inst_id = static_cast<opcode_e>(decoder->decode_instruction(instr));
|
auto inst_id = decode_inst_id(instr);
|
||||||
// pre execution stuff
|
// pre execution stuff
|
||||||
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
|
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
|
||||||
switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %>
|
switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %>
|
||||||
case opcode_e::${instr.name}: {
|
case arch::traits<ARCH>::opcode_e::${instr.name}: {
|
||||||
<%instr.fields.eachLine{%>${it}
|
<%instr.fields.eachLine{%>${it}
|
||||||
<%}%>if(this->disass_enabled){
|
<%}%>if(this->disass_enabled){
|
||||||
/* generate console output when executing the command */<%instr.disass.eachLine{%>
|
/* generate console output when executing the command */<%instr.disass.eachLine{%>
|
||||||
|
@ -236,8 +309,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
}
|
}
|
||||||
// used registers<%instr.usedVariables.each{ k,v->
|
// used registers<%instr.usedVariables.each{ k,v->
|
||||||
if(v.isArray) {%>
|
if(v.isArray) {%>
|
||||||
auto* ${k} = reinterpret_cast<uint${nativeTypeSize(v.type.size)}_t*>(this->regs_base_ptr+traits::reg_byte_offsets[traits::${k}0]);<% }else{ %>
|
auto* ${k} = reinterpret_cast<uint${nativeTypeSize(v.type.size)}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}0]);<% }else{ %>
|
||||||
auto* ${k} = reinterpret_cast<uint${nativeTypeSize(v.type.size)}_t*>(this->regs_base_ptr+traits::reg_byte_offsets[traits::${k}]);
|
auto* ${k} = reinterpret_cast<uint${nativeTypeSize(v.type.size)}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}]);
|
||||||
<%}}%>// calculate next pc value
|
<%}}%>// calculate next pc value
|
||||||
*NEXT_PC = *PC + ${instr.length/8};
|
*NEXT_PC = *PC + ${instr.length/8};
|
||||||
// execute instruction<%instr.behavior.eachLine{%>
|
// execute instruction<%instr.behavior.eachLine{%>
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iss/arch/traits.h>
|
#include <iss/arch/traits.h>
|
||||||
#include <iss/arch_if.h>
|
#include <iss/arch_if.h>
|
||||||
#include <iss/arch/instruction_decoder.h>
|
|
||||||
#include <iss/vm_if.h>
|
#include <iss/vm_if.h>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
|
@ -177,8 +176,6 @@ template <> struct traits<tgc_c> {
|
||||||
DII = 89,
|
DII = 89,
|
||||||
MAX_OPCODE
|
MAX_OPCODE
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::unique_ptr<instruction_decoder<tgc_c>> get_decoder();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tgc_c: public arch_if {
|
struct tgc_c: public arch_if {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue