allows functions in interp and updates generated
This commit is contained in:
parent
d5763d2f36
commit
e21f8dc379
@ -15,59 +15,51 @@ RV32I:
|
||||
- JAL:
|
||||
encoding: 0b00000000000000000000000001101111
|
||||
mask: 0b00000000000000000000000001111111
|
||||
attributes: [[name:no_cont]]
|
||||
size: 32
|
||||
branch: true
|
||||
delay: 1
|
||||
- JALR:
|
||||
encoding: 0b00000000000000000000000001100111
|
||||
mask: 0b00000000000000000111000001111111
|
||||
attributes: [[name:no_cont]]
|
||||
size: 32
|
||||
branch: true
|
||||
delay: 1
|
||||
- BEQ:
|
||||
encoding: 0b00000000000000000000000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
attributes: [[name:no_cont], [name:cond]]
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
delay: 1
|
||||
- BNE:
|
||||
encoding: 0b00000000000000000001000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
attributes: [[name:no_cont], [name:cond]]
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
delay: 1
|
||||
- BLT:
|
||||
encoding: 0b00000000000000000100000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
attributes: [[name:no_cont], [name:cond]]
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
delay: 1
|
||||
- BGE:
|
||||
encoding: 0b00000000000000000101000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
attributes: [[name:no_cont], [name:cond]]
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
delay: 1
|
||||
- BLTU:
|
||||
encoding: 0b00000000000000000110000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
attributes: [[name:no_cont], [name:cond]]
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
delay: 1
|
||||
- BGEU:
|
||||
encoding: 0b00000000000000000111000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
attributes: [[name:no_cont], [name:cond]]
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
delay: 1
|
||||
- LB:
|
||||
encoding: 0b00000000000000000000000000000011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
@ -239,14 +231,12 @@ RV32I:
|
||||
- ECALL:
|
||||
encoding: 0b00000000000000000000000001110011
|
||||
mask: 0b11111111111111111111111111111111
|
||||
attributes: [[name:no_cont]]
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
- EBREAK:
|
||||
encoding: 0b00000000000100000000000001110011
|
||||
mask: 0b11111111111111111111111111111111
|
||||
attributes: [[name:no_cont]]
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
@ -391,7 +381,6 @@ RV32IC:
|
||||
- CJAL:
|
||||
encoding: 0b0010000000000001
|
||||
mask: 0b1110000000000011
|
||||
attributes: [[name:no_cont]]
|
||||
size: 16
|
||||
branch: true
|
||||
delay: 1
|
||||
@ -458,24 +447,21 @@ RV32IC:
|
||||
- CJ:
|
||||
encoding: 0b1010000000000001
|
||||
mask: 0b1110000000000011
|
||||
attributes: [[name:no_cont]]
|
||||
size: 16
|
||||
branch: true
|
||||
delay: 1
|
||||
- CBEQZ:
|
||||
encoding: 0b1100000000000001
|
||||
mask: 0b1110000000000011
|
||||
attributes: [[name:no_cont], [name:cond]]
|
||||
size: 16
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
delay: 1
|
||||
- CBNEZ:
|
||||
encoding: 0b1110000000000001
|
||||
mask: 0b1110000000000011
|
||||
attributes: [[name:no_cont], [name:cond]]
|
||||
size: 16
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
delay: 1
|
||||
- CSLLI:
|
||||
encoding: 0b0000000000000010
|
||||
mask: 0b1111000000000011
|
||||
@ -497,7 +483,6 @@ RV32IC:
|
||||
- CJR:
|
||||
encoding: 0b1000000000000010
|
||||
mask: 0b1111000001111111
|
||||
attributes: [[name:no_cont]]
|
||||
size: 16
|
||||
branch: true
|
||||
delay: 1
|
||||
@ -510,14 +495,12 @@ RV32IC:
|
||||
- CJALR:
|
||||
encoding: 0b1001000000000010
|
||||
mask: 0b1111000001111111
|
||||
attributes: [[name:no_cont]]
|
||||
size: 16
|
||||
branch: true
|
||||
delay: 1
|
||||
- CEBREAK:
|
||||
encoding: 0b1001000000000010
|
||||
mask: 0b1111111111111111
|
||||
attributes: [[name:no_cont]]
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
@ -530,7 +513,6 @@ RV32IC:
|
||||
- DII:
|
||||
encoding: 0b0000000000000000
|
||||
mask: 0b1111111111111111
|
||||
attributes: [[name:no_cont]]
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
|
@ -43,6 +43,7 @@ def nativeTypeSize(int size){
|
||||
#include <sstream>
|
||||
#include <boost/coroutine2/all.hpp>
|
||||
#include <functional>
|
||||
#include <exception>
|
||||
|
||||
#ifndef FMT_HEADER_ONLY
|
||||
#define FMT_HEADER_ONLY
|
||||
@ -59,6 +60,10 @@ using namespace iss::arch;
|
||||
using namespace iss::debugger;
|
||||
using namespace std::placeholders;
|
||||
|
||||
struct memory_access_exception : public std::exception{
|
||||
memory_access_exception(){}
|
||||
};
|
||||
|
||||
template <typename ARCH> class vm_impl : public iss::interp::vm_base<ARCH> {
|
||||
public:
|
||||
using traits = arch::traits<ARCH>;
|
||||
@ -91,30 +96,9 @@ protected:
|
||||
|
||||
inline const char *name(size_t index){return index<traits::reg_aliases.size()?traits::reg_aliases[index]:"illegal";}
|
||||
|
||||
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;
|
||||
|
||||
// some compile time constants
|
||||
// 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(static_cast<uint32_t>(EXTR_MASK32)),
|
||||
LUT_SIZE_C = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK16))
|
||||
};
|
||||
|
||||
std::array<compile_func, LUT_SIZE> lut;
|
||||
|
||||
std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
|
||||
std::array<compile_func, LUT_SIZE> lut_11;
|
||||
|
||||
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){
|
||||
auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id;
|
||||
@ -314,28 +298,30 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
// pre execution stuff
|
||||
this->core.reg.last_branch = 0;
|
||||
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
|
||||
switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %>
|
||||
case arch::traits<ARCH>::opcode_e::${instr.name}: {
|
||||
<%instr.fields.eachLine{%>${it}
|
||||
<%}%>if(this->disass_enabled){
|
||||
/* generate console output when executing the command */<%instr.disass.eachLine{%>
|
||||
try{
|
||||
switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %>
|
||||
case arch::traits<ARCH>::opcode_e::${instr.name}: {
|
||||
<%instr.fields.eachLine{%>${it}
|
||||
<%}%>if(this->disass_enabled){
|
||||
/* generate console output when executing the command */<%instr.disass.eachLine{%>
|
||||
${it}<%}%>
|
||||
}
|
||||
// used registers<%instr.usedVariables.each{ k,v->
|
||||
if(v.isArray) {%>
|
||||
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+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}]);
|
||||
<%}}%>// calculate next pc value
|
||||
*NEXT_PC = *PC + ${instr.length/8};
|
||||
// execute instruction<%instr.behavior.eachLine{%>
|
||||
${it}<%}%>
|
||||
break;
|
||||
}// @suppress("No break at end of case")<%}%>
|
||||
default: {
|
||||
*NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2);
|
||||
raise(0, 2);
|
||||
}
|
||||
// used registers<%instr.usedVariables.each{ k,v->
|
||||
if(v.isArray) {%>
|
||||
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+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}]);
|
||||
<%}}%>// calculate next pc value
|
||||
*NEXT_PC = *PC + ${instr.length/8};
|
||||
// execute instruction<%instr.behavior.eachLine{%>
|
||||
${it}<%}%>
|
||||
TRAP_${instr.name}:break;
|
||||
}// @suppress("No break at end of case")<%}%>
|
||||
default: {
|
||||
*NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2);
|
||||
raise(0, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(memory_access_exception& e){}
|
||||
// post execution stuff
|
||||
process_spawn_blocks();
|
||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast<unsigned>(inst_id));
|
||||
|
@ -167,8 +167,9 @@ private:
|
||||
auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]);
|
||||
pc=pc+ ${instr.length/8};
|
||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||
tu.open_scope();<%instr.behavior.eachLine{%>
|
||||
${it}<%}%>
|
||||
tu.open_scope();
|
||||
<%instr.behavior.eachLine{%>${it}
|
||||
<%}%>
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,${idx});
|
||||
gen_trap_check(tu);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -120,57 +120,7 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
// some compile time constants
|
||||
// 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(static_cast<uint32_t>(EXTR_MASK32)), LUT_SIZE_C = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK16)) };
|
||||
|
||||
std::array<compile_func, LUT_SIZE> lut;
|
||||
|
||||
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 *, 4> qlut;
|
||||
|
||||
std::array<const uint32_t, 4> lutmasks = {{EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32}};
|
||||
|
||||
void expand_bit_mask(int pos, uint32_t mask, uint32_t value, uint32_t valid, uint32_t idx, compile_func lut[],
|
||||
compile_func f) {
|
||||
if (pos < 0) {
|
||||
lut[idx] = f;
|
||||
} else {
|
||||
auto bitmask = 1UL << pos;
|
||||
if ((mask & bitmask) == 0) {
|
||||
expand_bit_mask(pos - 1, mask, value, valid, idx, lut, f);
|
||||
} else {
|
||||
if ((valid & bitmask) == 0) {
|
||||
expand_bit_mask(pos - 1, mask, value, valid, (idx << 1), lut, f);
|
||||
expand_bit_mask(pos - 1, mask, value, valid, (idx << 1) + 1, lut, f);
|
||||
} else {
|
||||
auto new_val = idx << 1;
|
||||
if ((value & bitmask) != 0) new_val++;
|
||||
expand_bit_mask(pos - 1, mask, value, valid, new_val, lut, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32_t extract_fields(uint32_t val) { return extract_fields(29, val >> 2, lutmasks[val & 0x3], 0); }
|
||||
|
||||
uint32_t extract_fields(int pos, uint32_t val, uint32_t mask, uint32_t lut_val) {
|
||||
if (pos >= 0) {
|
||||
auto bitmask = 1UL << pos;
|
||||
if ((mask & bitmask) == 0) {
|
||||
lut_val = extract_fields(pos - 1, val, mask, lut_val);
|
||||
} else {
|
||||
auto new_val = lut_val << 1;
|
||||
if ((val & bitmask) != 0) new_val++;
|
||||
lut_val = extract_fields(pos - 1, val, mask, new_val);
|
||||
}
|
||||
}
|
||||
return lut_val;
|
||||
}
|
||||
|
||||
template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
|
||||
inline S sext(U from) {
|
||||
auto mask = (1ULL<<W) - 1;
|
||||
@ -182,14 +132,23 @@ private:
|
||||
/****************************************************************************
|
||||
* start opcode definitions
|
||||
****************************************************************************/
|
||||
struct InstructionDesriptor {
|
||||
struct instruction_descriptor {
|
||||
size_t length;
|
||||
uint32_t value;
|
||||
uint32_t mask;
|
||||
compile_func op;
|
||||
};
|
||||
struct decoding_tree_node{
|
||||
std::vector<instruction_descriptor> instrs;
|
||||
std::vector<decoding_tree_node*> children;
|
||||
uint32_t submask = std::numeric_limits<uint32_t>::max();
|
||||
uint32_t value;
|
||||
decoding_tree_node(uint32_t value) : value(value){}
|
||||
};
|
||||
|
||||
const std::array<InstructionDesriptor, 87> instr_descr = {{
|
||||
decoding_tree_node* root {nullptr};
|
||||
|
||||
const std::array<instruction_descriptor, 87> instr_descr = {{
|
||||
/* entries are: size, valid value, valid mask, function ptr */
|
||||
/* instruction LUI, encoding '0b00000000000000000000000000110111' */
|
||||
{32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui},
|
||||
@ -394,6 +353,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,0);
|
||||
gen_trap_check(tu);
|
||||
@ -426,6 +386,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,1);
|
||||
gen_trap_check(tu);
|
||||
@ -465,6 +426,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,2);
|
||||
gen_trap_check(tu);
|
||||
@ -506,6 +468,7 @@ private:
|
||||
tu.close_scope();
|
||||
}
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,3);
|
||||
gen_trap_check(tu);
|
||||
@ -545,6 +508,7 @@ private:
|
||||
tu.close_scope();
|
||||
}
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,4);
|
||||
gen_trap_check(tu);
|
||||
@ -584,6 +548,7 @@ private:
|
||||
tu.close_scope();
|
||||
}
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,5);
|
||||
gen_trap_check(tu);
|
||||
@ -623,6 +588,7 @@ private:
|
||||
tu.close_scope();
|
||||
}
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,6);
|
||||
gen_trap_check(tu);
|
||||
@ -662,6 +628,7 @@ private:
|
||||
tu.close_scope();
|
||||
}
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,7);
|
||||
gen_trap_check(tu);
|
||||
@ -701,6 +668,7 @@ private:
|
||||
tu.close_scope();
|
||||
}
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,8);
|
||||
gen_trap_check(tu);
|
||||
@ -740,6 +708,7 @@ private:
|
||||
tu.close_scope();
|
||||
}
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,9);
|
||||
gen_trap_check(tu);
|
||||
@ -775,6 +744,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,10);
|
||||
gen_trap_check(tu);
|
||||
@ -810,6 +780,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,11);
|
||||
gen_trap_check(tu);
|
||||
@ -845,6 +816,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,12);
|
||||
gen_trap_check(tu);
|
||||
@ -880,6 +852,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,13);
|
||||
gen_trap_check(tu);
|
||||
@ -915,6 +888,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,14);
|
||||
gen_trap_check(tu);
|
||||
@ -947,6 +921,7 @@ private:
|
||||
tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),8,true));
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,15);
|
||||
gen_trap_check(tu);
|
||||
@ -979,6 +954,7 @@ private:
|
||||
tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),16,true));
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,16);
|
||||
gen_trap_check(tu);
|
||||
@ -1011,6 +987,7 @@ private:
|
||||
tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),32,true));
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,17);
|
||||
gen_trap_check(tu);
|
||||
@ -1044,6 +1021,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,18);
|
||||
gen_trap_check(tu);
|
||||
@ -1077,6 +1055,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,19);
|
||||
gen_trap_check(tu);
|
||||
@ -1110,6 +1089,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,20);
|
||||
gen_trap_check(tu);
|
||||
@ -1143,6 +1123,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,21);
|
||||
gen_trap_check(tu);
|
||||
@ -1176,6 +1157,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,22);
|
||||
gen_trap_check(tu);
|
||||
@ -1209,6 +1191,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,23);
|
||||
gen_trap_check(tu);
|
||||
@ -1242,6 +1225,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,24);
|
||||
gen_trap_check(tu);
|
||||
@ -1275,6 +1259,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,25);
|
||||
gen_trap_check(tu);
|
||||
@ -1308,6 +1293,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,26);
|
||||
gen_trap_check(tu);
|
||||
@ -1341,6 +1327,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,27);
|
||||
gen_trap_check(tu);
|
||||
@ -1374,6 +1361,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,28);
|
||||
gen_trap_check(tu);
|
||||
@ -1407,6 +1395,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,29);
|
||||
gen_trap_check(tu);
|
||||
@ -1440,6 +1429,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,30);
|
||||
gen_trap_check(tu);
|
||||
@ -1473,6 +1463,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,31);
|
||||
gen_trap_check(tu);
|
||||
@ -1506,6 +1497,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,32);
|
||||
gen_trap_check(tu);
|
||||
@ -1539,6 +1531,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,33);
|
||||
gen_trap_check(tu);
|
||||
@ -1572,6 +1565,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,34);
|
||||
gen_trap_check(tu);
|
||||
@ -1605,6 +1599,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,35);
|
||||
gen_trap_check(tu);
|
||||
@ -1638,6 +1633,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,36);
|
||||
gen_trap_check(tu);
|
||||
@ -1666,6 +1662,7 @@ private:
|
||||
tu.open_scope();
|
||||
tu.write_mem(traits::FENCE, static_cast<uint32_t>(traits:: fence), tu.constant((uint8_t)pred<< 4|succ,8));
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,37);
|
||||
gen_trap_check(tu);
|
||||
@ -1686,6 +1683,7 @@ private:
|
||||
tu.open_scope();
|
||||
this->gen_raise_trap(tu, 0, 11);
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,38);
|
||||
gen_trap_check(tu);
|
||||
@ -1706,6 +1704,7 @@ private:
|
||||
tu.open_scope();
|
||||
this->gen_raise_trap(tu, 0, 3);
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,39);
|
||||
gen_trap_check(tu);
|
||||
@ -1726,6 +1725,7 @@ private:
|
||||
tu.open_scope();
|
||||
this->gen_leave_trap(tu, 3);
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,40);
|
||||
gen_trap_check(tu);
|
||||
@ -1746,6 +1746,7 @@ private:
|
||||
tu.open_scope();
|
||||
this->gen_wait(tu, 1);
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,41);
|
||||
gen_trap_check(tu);
|
||||
@ -1784,6 +1785,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,42);
|
||||
gen_trap_check(tu);
|
||||
@ -1822,6 +1824,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,43);
|
||||
gen_trap_check(tu);
|
||||
@ -1860,6 +1863,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,44);
|
||||
gen_trap_check(tu);
|
||||
@ -1895,6 +1899,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,45);
|
||||
gen_trap_check(tu);
|
||||
@ -1932,6 +1937,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,46);
|
||||
gen_trap_check(tu);
|
||||
@ -1969,6 +1975,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,47);
|
||||
gen_trap_check(tu);
|
||||
@ -1995,6 +2002,7 @@ private:
|
||||
tu.open_scope();
|
||||
tu.write_mem(traits::FENCE, static_cast<uint32_t>(traits:: fencei), tu.constant(imm,16));
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,48);
|
||||
gen_trap_check(tu);
|
||||
@ -2029,6 +2037,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,49);
|
||||
gen_trap_check(tu);
|
||||
@ -2063,6 +2072,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,50);
|
||||
gen_trap_check(tu);
|
||||
@ -2097,6 +2107,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,51);
|
||||
gen_trap_check(tu);
|
||||
@ -2131,6 +2142,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,52);
|
||||
gen_trap_check(tu);
|
||||
@ -2174,6 +2186,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,53);
|
||||
gen_trap_check(tu);
|
||||
@ -2213,6 +2226,7 @@ private:
|
||||
tu.close_scope();
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,54);
|
||||
gen_trap_check(tu);
|
||||
@ -2259,6 +2273,7 @@ private:
|
||||
tu.close_scope();
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,55);
|
||||
gen_trap_check(tu);
|
||||
@ -2298,6 +2313,7 @@ private:
|
||||
tu.close_scope();
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,56);
|
||||
gen_trap_check(tu);
|
||||
@ -2328,6 +2344,7 @@ private:
|
||||
this->gen_raise_trap(tu, 0, 2);
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,57);
|
||||
gen_trap_check(tu);
|
||||
@ -2355,6 +2372,7 @@ private:
|
||||
auto offs = tu.assignment(tu.ext((tu.add(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(uimm,8))),32,true),32);
|
||||
tu.store(rd+ 8 + traits::X0,tu.ext(tu.ext(tu.read_mem(traits::MEM, offs, 32),32,false),32,true));
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,58);
|
||||
gen_trap_check(tu);
|
||||
@ -2382,6 +2400,7 @@ private:
|
||||
auto offs = tu.assignment(tu.ext((tu.add(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(uimm,8))),32,true),32);
|
||||
tu.write_mem(traits::MEM, offs, tu.ext(tu.load(rs2+ 8+ traits::X0, 0),32,true));
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,59);
|
||||
gen_trap_check(tu);
|
||||
@ -2414,6 +2433,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,60);
|
||||
gen_trap_check(tu);
|
||||
@ -2434,6 +2454,7 @@ private:
|
||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||
tu.open_scope();
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,61);
|
||||
gen_trap_check(tu);
|
||||
@ -2461,6 +2482,7 @@ private:
|
||||
tu.store(traits::NEXT_PC, PC_val_v);
|
||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,62);
|
||||
gen_trap_check(tu);
|
||||
@ -2493,6 +2515,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,63);
|
||||
gen_trap_check(tu);
|
||||
@ -2523,6 +2546,7 @@ private:
|
||||
tu.store(rd + traits::X0,tu.constant((uint32_t)((int32_t)sext<18>(imm)),32));
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,64);
|
||||
gen_trap_check(tu);
|
||||
@ -2552,6 +2576,7 @@ private:
|
||||
this->gen_raise_trap(tu, 0, 2);
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,65);
|
||||
gen_trap_check(tu);
|
||||
@ -2573,6 +2598,7 @@ private:
|
||||
tu.open_scope();
|
||||
this->gen_raise_trap(tu, 0, 2);
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,66);
|
||||
gen_trap_check(tu);
|
||||
@ -2598,6 +2624,7 @@ private:
|
||||
tu.open_scope();
|
||||
tu.store(rs1+ 8 + traits::X0,tu.lshr(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(shamt,8)));
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,67);
|
||||
gen_trap_check(tu);
|
||||
@ -2628,6 +2655,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,68);
|
||||
gen_trap_check(tu);
|
||||
@ -2653,6 +2681,7 @@ private:
|
||||
tu.open_scope();
|
||||
tu.store(rs1+ 8 + traits::X0,tu.ext((tu.bitwise_and(tu.load(rs1+ 8+ traits::X0, 0),tu.constant((int8_t)sext<6>(imm),8))),32,true));
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,69);
|
||||
gen_trap_check(tu);
|
||||
@ -2678,6 +2707,7 @@ private:
|
||||
tu.open_scope();
|
||||
tu.store(rd+ 8 + traits::X0,tu.ext((tu.sub(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0))),32,true));
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,70);
|
||||
gen_trap_check(tu);
|
||||
@ -2703,6 +2733,7 @@ private:
|
||||
tu.open_scope();
|
||||
tu.store(rd+ 8 + traits::X0,tu.bitwise_xor(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0)));
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,71);
|
||||
gen_trap_check(tu);
|
||||
@ -2728,6 +2759,7 @@ private:
|
||||
tu.open_scope();
|
||||
tu.store(rd+ 8 + traits::X0,tu.bitwise_or(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0)));
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,72);
|
||||
gen_trap_check(tu);
|
||||
@ -2753,6 +2785,7 @@ private:
|
||||
tu.open_scope();
|
||||
tu.store(rd+ 8 + traits::X0,tu.bitwise_and(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0)));
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,73);
|
||||
gen_trap_check(tu);
|
||||
@ -2779,6 +2812,7 @@ private:
|
||||
tu.store(traits::NEXT_PC, PC_val_v);
|
||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,74);
|
||||
gen_trap_check(tu);
|
||||
@ -2808,6 +2842,7 @@ private:
|
||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
||||
tu.close_scope();
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,75);
|
||||
gen_trap_check(tu);
|
||||
@ -2837,6 +2872,7 @@ private:
|
||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
||||
tu.close_scope();
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,76);
|
||||
gen_trap_check(tu);
|
||||
@ -2869,6 +2905,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,77);
|
||||
gen_trap_check(tu);
|
||||
@ -2900,6 +2937,7 @@ private:
|
||||
tu.store(rd + traits::X0,tu.ext(tu.ext(tu.read_mem(traits::MEM, offs, 32),32,false),32,true));
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,78);
|
||||
gen_trap_check(tu);
|
||||
@ -2932,6 +2970,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,79);
|
||||
gen_trap_check(tu);
|
||||
@ -2963,6 +3002,7 @@ private:
|
||||
this->gen_raise_trap(tu, 0, 2);
|
||||
}
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,80);
|
||||
gen_trap_check(tu);
|
||||
@ -2983,6 +3023,7 @@ private:
|
||||
tu.open_scope();
|
||||
this->gen_raise_trap(tu, 0, 2);
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,81);
|
||||
gen_trap_check(tu);
|
||||
@ -3015,6 +3056,7 @@ private:
|
||||
}
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,82);
|
||||
gen_trap_check(tu);
|
||||
@ -3048,6 +3090,7 @@ private:
|
||||
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
|
||||
}
|
||||
auto returnValue = std::make_tuple(BRANCH);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,83);
|
||||
gen_trap_check(tu);
|
||||
@ -3068,6 +3111,7 @@ private:
|
||||
tu.open_scope();
|
||||
this->gen_raise_trap(tu, 0, 3);
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,84);
|
||||
gen_trap_check(tu);
|
||||
@ -3099,6 +3143,7 @@ private:
|
||||
tu.write_mem(traits::MEM, offs, tu.ext(tu.load(rs2+ traits::X0, 0),32,true));
|
||||
}
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,85);
|
||||
gen_trap_check(tu);
|
||||
@ -3119,6 +3164,7 @@ private:
|
||||
tu.open_scope();
|
||||
this->gen_raise_trap(tu, 0, 2);
|
||||
auto returnValue = std::make_tuple(CONT);
|
||||
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,86);
|
||||
gen_trap_check(tu);
|
||||
@ -3136,6 +3182,59 @@ private:
|
||||
vm_impl::gen_trap_check(tu);
|
||||
return BRANCH;
|
||||
}
|
||||
|
||||
//decoding functionality
|
||||
|
||||
void populate_decoding_tree(decoding_tree_node* root){
|
||||
//create submask
|
||||
for(auto instr: root->instrs){
|
||||
root->submask &= instr.mask;
|
||||
}
|
||||
//put each instr according to submask&encoding into children
|
||||
for(auto instr: root->instrs){
|
||||
bool foundMatch = false;
|
||||
for(auto child: root->children){
|
||||
//use value as identifying trait
|
||||
if(child->value == (instr.value&root->submask)){
|
||||
child->instrs.push_back(instr);
|
||||
foundMatch = true;
|
||||
}
|
||||
}
|
||||
if(!foundMatch){
|
||||
decoding_tree_node* child = new decoding_tree_node(instr.value&root->submask);
|
||||
child->instrs.push_back(instr);
|
||||
root->children.push_back(child);
|
||||
}
|
||||
}
|
||||
root->instrs.clear();
|
||||
//call populate_decoding_tree for all children
|
||||
if(root->children.size() >1)
|
||||
for(auto child: root->children){
|
||||
populate_decoding_tree(child);
|
||||
}
|
||||
else{
|
||||
//sort instrs by value of the mask, this works bc we want to have the least restrictive one last
|
||||
std::sort(root->children[0]->instrs.begin(), root->children[0]->instrs.end(), [](const instruction_descriptor& instr1, const instruction_descriptor& instr2) {
|
||||
return instr1.mask > instr2.mask;
|
||||
});
|
||||
}
|
||||
}
|
||||
compile_func decode_instr(decoding_tree_node* node, code_word_t word){
|
||||
if(!node->children.size()){
|
||||
if(node->instrs.size() == 1) return node->instrs[0].op;
|
||||
for(auto instr : node->instrs){
|
||||
if((instr.mask&word) == instr.value) return instr.op;
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(auto child : node->children){
|
||||
if (child->value == (node->submask&word)){
|
||||
return decode_instr(child, word);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CODE_WORD> void debug_fn(CODE_WORD instr) {
|
||||
@ -3148,14 +3247,11 @@ template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); }
|
||||
template <typename ARCH>
|
||||
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
||||
: vm_base<ARCH>(core, core_id, cluster_id) {
|
||||
qlut[0] = lut_00.data();
|
||||
qlut[1] = lut_01.data();
|
||||
qlut[2] = lut_10.data();
|
||||
qlut[3] = lut_11.data();
|
||||
for (auto instr : instr_descr) {
|
||||
auto quantrant = instr.value & 0x3;
|
||||
expand_bit_mask(29, lutmasks[quantrant], instr.value >> 2, instr.mask >> 2, 0, qlut[quantrant], instr.op);
|
||||
root = new decoding_tree_node(std::numeric_limits<uint32_t>::max());
|
||||
for(auto instr:instr_descr){
|
||||
root->instrs.push_back(instr);
|
||||
}
|
||||
populate_decoding_tree(root);
|
||||
}
|
||||
|
||||
template <typename ARCH>
|
||||
@ -3171,7 +3267,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||
// 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 ((instr & 0x3) == 0x3) { // this is a 32bit instruction
|
||||
// if ((insn & 0x3) == 0x3) { // this is a 32bit instruction
|
||||
// res = this->core.read(this->core.v2p(pc + 2), 2, data + 2);
|
||||
// }
|
||||
// } else {
|
||||
@ -3181,8 +3277,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||
if (instr == 0x0000006f || (instr&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||
// curr pc on stack
|
||||
++inst_cnt;
|
||||
auto lut_val = extract_fields(instr);
|
||||
auto f = qlut[instr & 0x3][lut_val];
|
||||
auto f = decode_instr(root, instr);
|
||||
if (f == nullptr) {
|
||||
f = &this_class::illegal_intruction;
|
||||
}
|
||||
@ -3218,7 +3313,7 @@ std::unique_ptr<vm_if> create<arch::tgc5c>(arch::tgc5c *core, unsigned short por
|
||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
|
||||
return std::unique_ptr<vm_if>(ret);
|
||||
}
|
||||
} // namespace tcc
|
||||
} // namesapce tcc
|
||||
} // namespace iss
|
||||
|
||||
#include <iss/factory.h>
|
||||
|
Loading…
Reference in New Issue
Block a user