3 Commits

9 changed files with 6463 additions and 5987 deletions

View File

@ -95,6 +95,7 @@ if(TARGET RapidJSON)
endif() endif()
if(WITH_LLVM) if(WITH_LLVM)
find_package(LLVM)
target_compile_definitions(${PROJECT_NAME} PUBLIC ${LLVM_DEFINITIONS}) target_compile_definitions(${PROJECT_NAME} PUBLIC ${LLVM_DEFINITIONS})
target_include_directories(${PROJECT_NAME} PUBLIC ${LLVM_INCLUDE_DIRS}) target_include_directories(${PROJECT_NAME} PUBLIC ${LLVM_INCLUDE_DIRS})
if(BUILD_SHARED_LIBS) if(BUILD_SHARED_LIBS)

View File

@ -15,59 +15,51 @@ RV32I:
- JAL: - JAL:
encoding: 0b00000000000000000000000001101111 encoding: 0b00000000000000000000000001101111
mask: 0b00000000000000000000000001111111 mask: 0b00000000000000000000000001111111
attributes: [[name:no_cont]]
size: 32 size: 32
branch: true branch: true
delay: 1 delay: 1
- JALR: - JALR:
encoding: 0b00000000000000000000000001100111 encoding: 0b00000000000000000000000001100111
mask: 0b00000000000000000111000001111111 mask: 0b00000000000000000111000001111111
attributes: [[name:no_cont]]
size: 32 size: 32
branch: true branch: true
delay: 1 delay: 1
- BEQ: - BEQ:
encoding: 0b00000000000000000000000001100011 encoding: 0b00000000000000000000000001100011
mask: 0b00000000000000000111000001111111 mask: 0b00000000000000000111000001111111
attributes: [[name:no_cont], [name:cond]]
size: 32 size: 32
branch: true branch: true
delay: [1,1] delay: 1
- BNE: - BNE:
encoding: 0b00000000000000000001000001100011 encoding: 0b00000000000000000001000001100011
mask: 0b00000000000000000111000001111111 mask: 0b00000000000000000111000001111111
attributes: [[name:no_cont], [name:cond]]
size: 32 size: 32
branch: true branch: true
delay: [1,1] delay: 1
- BLT: - BLT:
encoding: 0b00000000000000000100000001100011 encoding: 0b00000000000000000100000001100011
mask: 0b00000000000000000111000001111111 mask: 0b00000000000000000111000001111111
attributes: [[name:no_cont], [name:cond]]
size: 32 size: 32
branch: true branch: true
delay: [1,1] delay: 1
- BGE: - BGE:
encoding: 0b00000000000000000101000001100011 encoding: 0b00000000000000000101000001100011
mask: 0b00000000000000000111000001111111 mask: 0b00000000000000000111000001111111
attributes: [[name:no_cont], [name:cond]]
size: 32 size: 32
branch: true branch: true
delay: [1,1] delay: 1
- BLTU: - BLTU:
encoding: 0b00000000000000000110000001100011 encoding: 0b00000000000000000110000001100011
mask: 0b00000000000000000111000001111111 mask: 0b00000000000000000111000001111111
attributes: [[name:no_cont], [name:cond]]
size: 32 size: 32
branch: true branch: true
delay: [1,1] delay: 1
- BGEU: - BGEU:
encoding: 0b00000000000000000111000001100011 encoding: 0b00000000000000000111000001100011
mask: 0b00000000000000000111000001111111 mask: 0b00000000000000000111000001111111
attributes: [[name:no_cont], [name:cond]]
size: 32 size: 32
branch: true branch: true
delay: [1,1] delay: 1
- LB: - LB:
encoding: 0b00000000000000000000000000000011 encoding: 0b00000000000000000000000000000011
mask: 0b00000000000000000111000001111111 mask: 0b00000000000000000111000001111111
@ -239,14 +231,12 @@ RV32I:
- ECALL: - ECALL:
encoding: 0b00000000000000000000000001110011 encoding: 0b00000000000000000000000001110011
mask: 0b11111111111111111111111111111111 mask: 0b11111111111111111111111111111111
attributes: [[name:no_cont]]
size: 32 size: 32
branch: false branch: false
delay: 1 delay: 1
- EBREAK: - EBREAK:
encoding: 0b00000000000100000000000001110011 encoding: 0b00000000000100000000000001110011
mask: 0b11111111111111111111111111111111 mask: 0b11111111111111111111111111111111
attributes: [[name:no_cont]]
size: 32 size: 32
branch: false branch: false
delay: 1 delay: 1
@ -391,7 +381,6 @@ RV32IC:
- CJAL: - CJAL:
encoding: 0b0010000000000001 encoding: 0b0010000000000001
mask: 0b1110000000000011 mask: 0b1110000000000011
attributes: [[name:no_cont]]
size: 16 size: 16
branch: true branch: true
delay: 1 delay: 1
@ -458,24 +447,21 @@ RV32IC:
- CJ: - CJ:
encoding: 0b1010000000000001 encoding: 0b1010000000000001
mask: 0b1110000000000011 mask: 0b1110000000000011
attributes: [[name:no_cont]]
size: 16 size: 16
branch: true branch: true
delay: 1 delay: 1
- CBEQZ: - CBEQZ:
encoding: 0b1100000000000001 encoding: 0b1100000000000001
mask: 0b1110000000000011 mask: 0b1110000000000011
attributes: [[name:no_cont], [name:cond]]
size: 16 size: 16
branch: true branch: true
delay: [1,1] delay: 1
- CBNEZ: - CBNEZ:
encoding: 0b1110000000000001 encoding: 0b1110000000000001
mask: 0b1110000000000011 mask: 0b1110000000000011
attributes: [[name:no_cont], [name:cond]]
size: 16 size: 16
branch: true branch: true
delay: [1,1] delay: 1
- CSLLI: - CSLLI:
encoding: 0b0000000000000010 encoding: 0b0000000000000010
mask: 0b1111000000000011 mask: 0b1111000000000011
@ -497,7 +483,6 @@ RV32IC:
- CJR: - CJR:
encoding: 0b1000000000000010 encoding: 0b1000000000000010
mask: 0b1111000001111111 mask: 0b1111000001111111
attributes: [[name:no_cont]]
size: 16 size: 16
branch: true branch: true
delay: 1 delay: 1
@ -510,14 +495,12 @@ RV32IC:
- CJALR: - CJALR:
encoding: 0b1001000000000010 encoding: 0b1001000000000010
mask: 0b1111000001111111 mask: 0b1111000001111111
attributes: [[name:no_cont]]
size: 16 size: 16
branch: true branch: true
delay: 1 delay: 1
- CEBREAK: - CEBREAK:
encoding: 0b1001000000000010 encoding: 0b1001000000000010
mask: 0b1111111111111111 mask: 0b1111111111111111
attributes: [[name:no_cont]]
size: 16 size: 16
branch: false branch: false
delay: 1 delay: 1
@ -530,7 +513,6 @@ RV32IC:
- DII: - DII:
encoding: 0b0000000000000000 encoding: 0b0000000000000000
mask: 0b1111111111111111 mask: 0b1111111111111111
attributes: [[name:no_cont]]
size: 16 size: 16
branch: false branch: false
delay: 1 delay: 1

View File

@ -43,6 +43,7 @@ def nativeTypeSize(int size){
#include <sstream> #include <sstream>
#include <boost/coroutine2/all.hpp> #include <boost/coroutine2/all.hpp>
#include <functional> #include <functional>
#include <exception>
#ifndef FMT_HEADER_ONLY #ifndef FMT_HEADER_ONLY
#define FMT_HEADER_ONLY #define FMT_HEADER_ONLY
@ -59,6 +60,10 @@ using namespace iss::arch;
using namespace iss::debugger; using namespace iss::debugger;
using namespace std::placeholders; 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> { template <typename ARCH> class vm_impl : public iss::interp::vm_base<ARCH> {
public: public:
using traits = arch::traits<ARCH>; 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";} 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; 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
// 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){ 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;
@ -314,28 +298,30 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// pre execution stuff // pre execution stuff
this->core.reg.last_branch = 0; this->core.reg.last_branch = 0;
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 -> %> try{
case arch::traits<ARCH>::opcode_e::${instr.name}: { switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %>
<%instr.fields.eachLine{%>${it} case arch::traits<ARCH>::opcode_e::${instr.name}: {
<%}%>if(this->disass_enabled){ <%instr.fields.eachLine{%>${it}
/* generate console output when executing the command */<%instr.disass.eachLine{%> <%}%>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}<%}%> ${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) {%> }catch(memory_access_exception& e){}
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);
}
}
// post execution stuff // post execution stuff
process_spawn_blocks(); process_spawn_blocks();
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast<unsigned>(inst_id)); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast<unsigned>(inst_id));

View File

@ -58,6 +58,7 @@ using namespace iss::debugger;
template <typename ARCH> class vm_impl : public iss::llvm::vm_base<ARCH> { template <typename ARCH> class vm_impl : public iss::llvm::vm_base<ARCH> {
public: public:
using traits = arch::traits<ARCH>;
using super = typename iss::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;
@ -80,7 +81,7 @@ public:
protected: protected:
using vm_base<ARCH>::get_reg_ptr; using vm_base<ARCH>::get_reg_ptr;
inline const char *name(size_t index){return traits<ARCH>::reg_aliases.at(index);} inline const char *name(size_t index){return traits::reg_aliases.at(index);}
template <typename T> inline ConstantInt *size(T type) { template <typename T> inline ConstantInt *size(T type) {
return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits())); return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits()));
@ -88,7 +89,7 @@ protected:
void setup_module(Module* m) override { void setup_module(Module* m) override {
super::setup_module(m); super::setup_module(m);
iss::llvm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE, traits<ARCH>::XLEN); iss::llvm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE, traits::XLEN);
} }
inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) { inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) {
@ -114,88 +115,70 @@ protected:
} }
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { inline void 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), Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val),
this->get_type(traits<ARCH>::XLEN)); this->get_type(traits::XLEN));
this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
} }
// some compile time constants // 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<uint64_t>(EXTR_MASK32)), LUT_SIZE_C = 1 << util::bit_count(static_cast<uint64_t>(EXTR_MASK16)) };
using this_class = vm_impl<ARCH>; using this_class = vm_impl<ARCH>;
using compile_func = std::tuple<continuation_e, BasicBlock *> (this_class::*)(virt_addr_t &pc, using compile_func = std::tuple<continuation_e, BasicBlock *> (this_class::*)(virt_addr_t &pc,
code_word_t instr, code_word_t instr,
BasicBlock *bb); BasicBlock *bb);
std::array<compile_func, LUT_SIZE> lut; template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
inline S sext(U from) {
std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10; auto mask = (1ULL<<W) - 1;
std::array<compile_func, LUT_SIZE> lut_11; auto sign_mask = 1ULL<<(W-1);
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
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;
}
private: private:
/**************************************************************************** /****************************************************************************
* start opcode definitions * start opcode definitions
****************************************************************************/ ****************************************************************************/
struct InstructionDesriptor { struct instruction_descriptor {
size_t length; size_t length;
uint32_t value; uint32_t value;
uint32_t mask; uint32_t mask;
compile_func op; 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, ${instructions.size}> instr_descr = {{ decoding_tree_node* root {nullptr};
const std::array<instruction_descriptor, ${instructions.size}> instr_descr = {{
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %> /* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
/* instruction ${instr.instruction.name} */ /* instruction ${instr.instruction.name}, encoding '${instr.encoding}' */
{${instr.length}, ${instr.value}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%> {${instr.length}, ${instr.encoding}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
}}; }};
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %> /* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
/* instruction ${idx}: ${instr.name} */ /* instruction ${idx}: ${instr.name} */
std::tuple<continuation_e, BasicBlock*> __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){<%instr.code.eachLine{%> std::tuple<continuation_e, BasicBlock*> __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
${it}<%}%> bb->setName(fmt::format("${instr.name}_0x{:X}",pc.val));
this->gen_sync(PRE_SYNC,${idx});
uint64_t PC = pc.val;
<%instr.fields.eachLine{%>${it}
<%}%>if(this->disass_enabled){
/* generate console output when executing the command */<%instr.disass.eachLine{%>
${it}<%}%>
}
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ ${instr.length/8};
this->gen_set_pc(pc, traits::NEXT_PC);
<%instr.behavior.eachLine{%>${it}
<%}%>
this->gen_trap_check(bb);
this->gen_sync(POST_SYNC, ${idx});
this->builder.CreateBr(bb);
return returnValue;
} }
<%}%> <%}%>
/**************************************************************************** /****************************************************************************
@ -203,23 +186,75 @@ private:
****************************************************************************/ ****************************************************************************/
std::tuple<continuation_e, BasicBlock *> illegal_intruction(virt_addr_t &pc, code_word_t instr, BasicBlock *bb) { 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->gen_sync(iss::PRE_SYNC, instr_descr.size());
this->builder.CreateStore(this->builder.CreateLoad(this->get_typeptr(traits<ARCH>::NEXT_PC), get_reg_ptr(traits<ARCH>::NEXT_PC), true), this->builder.CreateStore(this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), true),
get_reg_ptr(traits<ARCH>::PC), true); get_reg_ptr(traits::PC), true);
this->builder.CreateStore( this->builder.CreateStore(
this->builder.CreateAdd(this->builder.CreateLoad(this->get_typeptr(traits<ARCH>::ICOUNT), get_reg_ptr(traits<ARCH>::ICOUNT), true), this->builder.CreateAdd(this->builder.CreateLoad(this->get_typeptr(traits::ICOUNT), get_reg_ptr(traits::ICOUNT), true),
this->gen_const(64U, 1)), this->gen_const(64U, 1)),
get_reg_ptr(traits<ARCH>::ICOUNT), true); get_reg_ptr(traits::ICOUNT), true);
pc = pc + ((instr & 3) == 3 ? 4 : 2); pc = pc + ((instr & 3) == 3 ? 4 : 2);
this->gen_raise_trap(0, 2); // illegal instruction trap this->gen_raise_trap(0, 2); // illegal instruction trap
this->gen_sync(iss::POST_SYNC, instr_descr.size()); this->gen_sync(iss::POST_SYNC, instr_descr.size());
this->gen_trap_check(this->leave_blk); this->gen_trap_check(this->leave_blk);
return std::make_tuple(BRANCH, nullptr); return std::make_tuple(BRANCH, nullptr);
}
//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 insn) { template <typename CODE_WORD> void debug_fn(CODE_WORD instr) {
volatile CODE_WORD x = insn; volatile CODE_WORD x = instr;
insn = 2 * x; instr = 2 * x;
} }
template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); } template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); }
@ -227,14 +262,11 @@ template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); }
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) {
qlut[0] = lut_00.data(); root = new decoding_tree_node(std::numeric_limits<uint32_t>::max());
qlut[1] = lut_01.data(); for(auto instr:instr_descr){
qlut[2] = lut_10.data(); root->instrs.push_back(instr);
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);
} }
populate_decoding_tree(root);
} }
template <typename ARCH> template <typename ARCH>
@ -242,50 +274,50 @@ std::tuple<continuation_e, BasicBlock *>
vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, BasicBlock *this_block) { 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 // we fetch at max 4 byte, alignment is 2
enum {TRAP_ID=1<<16}; enum {TRAP_ID=1<<16};
code_word_t insn = 0; code_word_t instr = 0;
// const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK; // const typename traits::addr_t upper_bits = ~traits::PGMASK;
phys_addr_t paddr(pc); phys_addr_t paddr(pc);
auto *const data = (uint8_t *)&insn; auto *const data = (uint8_t *)&instr;
paddr = this->core.v2p(pc); if(this->core.has_mmu())
paddr = this->core.virt2phys(pc);
//TODO: re-add page handling //TODO: re-add page handling
// if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary // if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
// auto res = this->core.read(paddr, 2, data); // auto res = this->core.read(paddr, 2, data);
// if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); // if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val);
// if ((insn & 0x3) == 0x3) { // this is a 32bit instruction // if ((instr & 0x3) == 0x3) { // this is a 32bit instruction
// res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); // res = this->core.read(this->core.v2p(pc + 2), 2, data + 2);
// } // }
// } else { // } else {
auto res = this->core.read(paddr, 4, data); auto res = this->core.read(paddr, 4, data);
if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); 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' if (instr == 0x0000006f || (instr&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
// curr pc on stack // curr pc on stack
++inst_cnt; ++inst_cnt;
auto lut_val = extract_fields(insn); auto f = decode_instr(root, instr);
auto f = qlut[insn & 0x3][lut_val];
if (f == nullptr) { if (f == nullptr) {
f = &this_class::illegal_intruction; f = &this_class::illegal_intruction;
} }
return (this->*f)(pc, insn, this_block); return (this->*f)(pc, instr, this_block);
} }
template <typename ARCH> void vm_impl<ARCH>::gen_leave_behavior(BasicBlock *leave_blk) { template <typename ARCH> void vm_impl<ARCH>::gen_leave_behavior(BasicBlock *leave_blk) {
this->builder.SetInsertPoint(leave_blk); this->builder.SetInsertPoint(leave_blk);
this->builder.CreateRet(this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::NEXT_PC), get_reg_ptr(arch::traits<ARCH>::NEXT_PC), false)); this->builder.CreateRet(this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC),get_reg_ptr(traits::NEXT_PC), false));
} }
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) { template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) {
auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id);
this->builder.CreateStore(TRAP_val, get_reg_ptr(traits<ARCH>::TRAP_STATE), true); this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true);
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits::LAST_BRANCH), false);
} }
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) { template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, lvl)) }; std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, lvl)) };
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args); this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
auto *PC_val = this->gen_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8); auto *PC_val = this->gen_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8);
this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false);
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits::LAST_BRANCH), false);
} }
template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) { template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
@ -295,22 +327,25 @@ template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) { template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
this->builder.SetInsertPoint(trap_blk); this->builder.SetInsertPoint(trap_blk);
auto *trap_state_val = this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::TRAP_STATE), get_reg_ptr(traits<ARCH>::TRAP_STATE), true); this->gen_sync(POST_SYNC, -1); //TODO get right InstrId
auto *trap_state_val = this->builder.CreateLoad(this->get_typeptr(traits::TRAP_STATE), get_reg_ptr(traits::TRAP_STATE), true);
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); get_reg_ptr(traits::LAST_BRANCH), false);
std::vector<Value *> args{this->core_ptr, this->adj_to64(trap_state_val), std::vector<Value *> args{this->core_ptr, this->adj_to64(trap_state_val),
this->adj_to64(this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::PC), get_reg_ptr(traits<ARCH>::PC), false))}; this->adj_to64(this->builder.CreateLoad(this->get_typeptr(traits::PC), get_reg_ptr(traits::PC), false))};
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
auto *trap_addr_val = this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::NEXT_PC), get_reg_ptr(traits<ARCH>::NEXT_PC), false); auto *trap_addr_val = this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), false);
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 void vm_impl<ARCH>::gen_trap_check(BasicBlock *bb) {
auto *v = this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::TRAP_STATE), get_reg_ptr(arch::traits<ARCH>::TRAP_STATE), true); auto* target_bb = BasicBlock::Create(this->mod->getContext(), "", this->func, bb);
auto *v = this->builder.CreateLoad(this->get_typeptr(traits::TRAP_STATE), get_reg_ptr(traits::TRAP_STATE), true);
this->gen_cond_branch(this->builder.CreateICmp( this->gen_cond_branch(this->builder.CreateICmp(
ICmpInst::ICMP_EQ, v, ICmpInst::ICMP_EQ, v,
ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))), ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))),
bb, this->trap_blk, 1); target_bb, this->trap_blk, 1);
this->builder.SetInsertPoint(target_bb);
} }
} // namespace ${coreDef.name.toLowerCase()} } // namespace ${coreDef.name.toLowerCase()}

View File

@ -167,8 +167,9 @@ private:
auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]);
pc=pc+ ${instr.length/8}; pc=pc+ ${instr.length/8};
gen_set_pc(tu, pc, traits::NEXT_PC); gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();<%instr.behavior.eachLine{%> tu.open_scope();
${it}<%}%> <%instr.behavior.eachLine{%>${it}
<%}%>
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,${idx}); vm_base<ARCH>::gen_sync(tu, POST_SYNC,${idx});
gen_trap_check(tu); gen_trap_check(tu);

View File

@ -1113,8 +1113,10 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned le
} }
this->reg.trap_state=std::numeric_limits<uint32_t>::max(); this->reg.trap_state=std::numeric_limits<uint32_t>::max();
this->interrupt_sim=hostvar; this->interrupt_sim=hostvar;
#ifndef WITH_TCC
throw(iss::simulation_stopped(hostvar));
#endif
break; break;
//throw(iss::simulation_stopped(hostvar));
case 0x0101: { case 0x0101: {
char c = static_cast<char>(hostvar & 0xff); char c = static_cast<char>(hostvar & 0xff);
if (c == '\n' || c == 0) { if (c == '\n' || c == 0) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -353,6 +353,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,0); vm_base<ARCH>::gen_sync(tu, POST_SYNC,0);
gen_trap_check(tu); gen_trap_check(tu);
@ -385,6 +386,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,1); vm_base<ARCH>::gen_sync(tu, POST_SYNC,1);
gen_trap_check(tu); gen_trap_check(tu);
@ -424,6 +426,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,2); vm_base<ARCH>::gen_sync(tu, POST_SYNC,2);
gen_trap_check(tu); gen_trap_check(tu);
@ -465,6 +468,7 @@ private:
tu.close_scope(); tu.close_scope();
} }
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,3); vm_base<ARCH>::gen_sync(tu, POST_SYNC,3);
gen_trap_check(tu); gen_trap_check(tu);
@ -504,6 +508,7 @@ private:
tu.close_scope(); tu.close_scope();
} }
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,4); vm_base<ARCH>::gen_sync(tu, POST_SYNC,4);
gen_trap_check(tu); gen_trap_check(tu);
@ -543,6 +548,7 @@ private:
tu.close_scope(); tu.close_scope();
} }
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,5); vm_base<ARCH>::gen_sync(tu, POST_SYNC,5);
gen_trap_check(tu); gen_trap_check(tu);
@ -582,6 +588,7 @@ private:
tu.close_scope(); tu.close_scope();
} }
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,6); vm_base<ARCH>::gen_sync(tu, POST_SYNC,6);
gen_trap_check(tu); gen_trap_check(tu);
@ -621,6 +628,7 @@ private:
tu.close_scope(); tu.close_scope();
} }
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,7); vm_base<ARCH>::gen_sync(tu, POST_SYNC,7);
gen_trap_check(tu); gen_trap_check(tu);
@ -660,6 +668,7 @@ private:
tu.close_scope(); tu.close_scope();
} }
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,8); vm_base<ARCH>::gen_sync(tu, POST_SYNC,8);
gen_trap_check(tu); gen_trap_check(tu);
@ -699,6 +708,7 @@ private:
tu.close_scope(); tu.close_scope();
} }
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,9); vm_base<ARCH>::gen_sync(tu, POST_SYNC,9);
gen_trap_check(tu); gen_trap_check(tu);
@ -734,6 +744,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,10); vm_base<ARCH>::gen_sync(tu, POST_SYNC,10);
gen_trap_check(tu); gen_trap_check(tu);
@ -769,6 +780,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,11); vm_base<ARCH>::gen_sync(tu, POST_SYNC,11);
gen_trap_check(tu); gen_trap_check(tu);
@ -804,6 +816,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,12); vm_base<ARCH>::gen_sync(tu, POST_SYNC,12);
gen_trap_check(tu); gen_trap_check(tu);
@ -839,6 +852,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,13); vm_base<ARCH>::gen_sync(tu, POST_SYNC,13);
gen_trap_check(tu); gen_trap_check(tu);
@ -874,6 +888,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,14); vm_base<ARCH>::gen_sync(tu, POST_SYNC,14);
gen_trap_check(tu); gen_trap_check(tu);
@ -906,6 +921,7 @@ private:
tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),8,true)); tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),8,true));
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,15); vm_base<ARCH>::gen_sync(tu, POST_SYNC,15);
gen_trap_check(tu); gen_trap_check(tu);
@ -938,6 +954,7 @@ private:
tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),16,true)); tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),16,true));
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,16); vm_base<ARCH>::gen_sync(tu, POST_SYNC,16);
gen_trap_check(tu); gen_trap_check(tu);
@ -970,6 +987,7 @@ private:
tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),32,true)); tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),32,true));
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,17); vm_base<ARCH>::gen_sync(tu, POST_SYNC,17);
gen_trap_check(tu); gen_trap_check(tu);
@ -1003,6 +1021,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,18); vm_base<ARCH>::gen_sync(tu, POST_SYNC,18);
gen_trap_check(tu); gen_trap_check(tu);
@ -1036,6 +1055,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,19); vm_base<ARCH>::gen_sync(tu, POST_SYNC,19);
gen_trap_check(tu); gen_trap_check(tu);
@ -1069,6 +1089,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,20); vm_base<ARCH>::gen_sync(tu, POST_SYNC,20);
gen_trap_check(tu); gen_trap_check(tu);
@ -1102,6 +1123,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,21); vm_base<ARCH>::gen_sync(tu, POST_SYNC,21);
gen_trap_check(tu); gen_trap_check(tu);
@ -1135,6 +1157,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,22); vm_base<ARCH>::gen_sync(tu, POST_SYNC,22);
gen_trap_check(tu); gen_trap_check(tu);
@ -1168,6 +1191,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,23); vm_base<ARCH>::gen_sync(tu, POST_SYNC,23);
gen_trap_check(tu); gen_trap_check(tu);
@ -1201,6 +1225,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,24); vm_base<ARCH>::gen_sync(tu, POST_SYNC,24);
gen_trap_check(tu); gen_trap_check(tu);
@ -1234,6 +1259,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,25); vm_base<ARCH>::gen_sync(tu, POST_SYNC,25);
gen_trap_check(tu); gen_trap_check(tu);
@ -1267,6 +1293,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,26); vm_base<ARCH>::gen_sync(tu, POST_SYNC,26);
gen_trap_check(tu); gen_trap_check(tu);
@ -1300,6 +1327,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,27); vm_base<ARCH>::gen_sync(tu, POST_SYNC,27);
gen_trap_check(tu); gen_trap_check(tu);
@ -1333,6 +1361,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,28); vm_base<ARCH>::gen_sync(tu, POST_SYNC,28);
gen_trap_check(tu); gen_trap_check(tu);
@ -1366,6 +1395,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,29); vm_base<ARCH>::gen_sync(tu, POST_SYNC,29);
gen_trap_check(tu); gen_trap_check(tu);
@ -1399,6 +1429,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,30); vm_base<ARCH>::gen_sync(tu, POST_SYNC,30);
gen_trap_check(tu); gen_trap_check(tu);
@ -1432,6 +1463,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,31); vm_base<ARCH>::gen_sync(tu, POST_SYNC,31);
gen_trap_check(tu); gen_trap_check(tu);
@ -1465,6 +1497,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,32); vm_base<ARCH>::gen_sync(tu, POST_SYNC,32);
gen_trap_check(tu); gen_trap_check(tu);
@ -1498,6 +1531,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,33); vm_base<ARCH>::gen_sync(tu, POST_SYNC,33);
gen_trap_check(tu); gen_trap_check(tu);
@ -1531,6 +1565,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,34); vm_base<ARCH>::gen_sync(tu, POST_SYNC,34);
gen_trap_check(tu); gen_trap_check(tu);
@ -1564,6 +1599,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,35); vm_base<ARCH>::gen_sync(tu, POST_SYNC,35);
gen_trap_check(tu); gen_trap_check(tu);
@ -1597,6 +1633,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,36); vm_base<ARCH>::gen_sync(tu, POST_SYNC,36);
gen_trap_check(tu); gen_trap_check(tu);
@ -1625,6 +1662,7 @@ private:
tu.open_scope(); tu.open_scope();
tu.write_mem(traits::FENCE, static_cast<uint32_t>(traits:: fence), tu.constant((uint8_t)pred<< 4|succ,8)); 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); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,37); vm_base<ARCH>::gen_sync(tu, POST_SYNC,37);
gen_trap_check(tu); gen_trap_check(tu);
@ -1645,6 +1683,7 @@ private:
tu.open_scope(); tu.open_scope();
this->gen_raise_trap(tu, 0, 11); this->gen_raise_trap(tu, 0, 11);
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,38); vm_base<ARCH>::gen_sync(tu, POST_SYNC,38);
gen_trap_check(tu); gen_trap_check(tu);
@ -1665,6 +1704,7 @@ private:
tu.open_scope(); tu.open_scope();
this->gen_raise_trap(tu, 0, 3); this->gen_raise_trap(tu, 0, 3);
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,39); vm_base<ARCH>::gen_sync(tu, POST_SYNC,39);
gen_trap_check(tu); gen_trap_check(tu);
@ -1685,6 +1725,7 @@ private:
tu.open_scope(); tu.open_scope();
this->gen_leave_trap(tu, 3); this->gen_leave_trap(tu, 3);
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,40); vm_base<ARCH>::gen_sync(tu, POST_SYNC,40);
gen_trap_check(tu); gen_trap_check(tu);
@ -1705,6 +1746,7 @@ private:
tu.open_scope(); tu.open_scope();
this->gen_wait(tu, 1); this->gen_wait(tu, 1);
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,41); vm_base<ARCH>::gen_sync(tu, POST_SYNC,41);
gen_trap_check(tu); gen_trap_check(tu);
@ -1743,6 +1785,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,42); vm_base<ARCH>::gen_sync(tu, POST_SYNC,42);
gen_trap_check(tu); gen_trap_check(tu);
@ -1781,6 +1824,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,43); vm_base<ARCH>::gen_sync(tu, POST_SYNC,43);
gen_trap_check(tu); gen_trap_check(tu);
@ -1819,6 +1863,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,44); vm_base<ARCH>::gen_sync(tu, POST_SYNC,44);
gen_trap_check(tu); gen_trap_check(tu);
@ -1854,6 +1899,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,45); vm_base<ARCH>::gen_sync(tu, POST_SYNC,45);
gen_trap_check(tu); gen_trap_check(tu);
@ -1891,6 +1937,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,46); vm_base<ARCH>::gen_sync(tu, POST_SYNC,46);
gen_trap_check(tu); gen_trap_check(tu);
@ -1928,6 +1975,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,47); vm_base<ARCH>::gen_sync(tu, POST_SYNC,47);
gen_trap_check(tu); gen_trap_check(tu);
@ -1954,6 +2002,7 @@ private:
tu.open_scope(); tu.open_scope();
tu.write_mem(traits::FENCE, static_cast<uint32_t>(traits:: fencei), tu.constant(imm,16)); tu.write_mem(traits::FENCE, static_cast<uint32_t>(traits:: fencei), tu.constant(imm,16));
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,48); vm_base<ARCH>::gen_sync(tu, POST_SYNC,48);
gen_trap_check(tu); gen_trap_check(tu);
@ -1988,6 +2037,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,49); vm_base<ARCH>::gen_sync(tu, POST_SYNC,49);
gen_trap_check(tu); gen_trap_check(tu);
@ -2022,6 +2072,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,50); vm_base<ARCH>::gen_sync(tu, POST_SYNC,50);
gen_trap_check(tu); gen_trap_check(tu);
@ -2056,6 +2107,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,51); vm_base<ARCH>::gen_sync(tu, POST_SYNC,51);
gen_trap_check(tu); gen_trap_check(tu);
@ -2090,6 +2142,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,52); vm_base<ARCH>::gen_sync(tu, POST_SYNC,52);
gen_trap_check(tu); gen_trap_check(tu);
@ -2133,6 +2186,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,53); vm_base<ARCH>::gen_sync(tu, POST_SYNC,53);
gen_trap_check(tu); gen_trap_check(tu);
@ -2172,6 +2226,7 @@ private:
tu.close_scope(); tu.close_scope();
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,54); vm_base<ARCH>::gen_sync(tu, POST_SYNC,54);
gen_trap_check(tu); gen_trap_check(tu);
@ -2218,6 +2273,7 @@ private:
tu.close_scope(); tu.close_scope();
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,55); vm_base<ARCH>::gen_sync(tu, POST_SYNC,55);
gen_trap_check(tu); gen_trap_check(tu);
@ -2257,6 +2313,7 @@ private:
tu.close_scope(); tu.close_scope();
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,56); vm_base<ARCH>::gen_sync(tu, POST_SYNC,56);
gen_trap_check(tu); gen_trap_check(tu);
@ -2287,6 +2344,7 @@ private:
this->gen_raise_trap(tu, 0, 2); this->gen_raise_trap(tu, 0, 2);
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,57); vm_base<ARCH>::gen_sync(tu, POST_SYNC,57);
gen_trap_check(tu); gen_trap_check(tu);
@ -2314,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); 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)); 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); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,58); vm_base<ARCH>::gen_sync(tu, POST_SYNC,58);
gen_trap_check(tu); gen_trap_check(tu);
@ -2341,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); 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)); tu.write_mem(traits::MEM, offs, tu.ext(tu.load(rs2+ 8+ traits::X0, 0),32,true));
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,59); vm_base<ARCH>::gen_sync(tu, POST_SYNC,59);
gen_trap_check(tu); gen_trap_check(tu);
@ -2373,6 +2433,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,60); vm_base<ARCH>::gen_sync(tu, POST_SYNC,60);
gen_trap_check(tu); gen_trap_check(tu);
@ -2393,6 +2454,7 @@ private:
gen_set_pc(tu, pc, traits::NEXT_PC); gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope(); tu.open_scope();
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,61); vm_base<ARCH>::gen_sync(tu, POST_SYNC,61);
gen_trap_check(tu); gen_trap_check(tu);
@ -2420,6 +2482,7 @@ private:
tu.store(traits::NEXT_PC, PC_val_v); tu.store(traits::NEXT_PC, PC_val_v);
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2)); tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,62); vm_base<ARCH>::gen_sync(tu, POST_SYNC,62);
gen_trap_check(tu); gen_trap_check(tu);
@ -2452,6 +2515,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,63); vm_base<ARCH>::gen_sync(tu, POST_SYNC,63);
gen_trap_check(tu); gen_trap_check(tu);
@ -2482,6 +2546,7 @@ private:
tu.store(rd + traits::X0,tu.constant((uint32_t)((int32_t)sext<18>(imm)),32)); tu.store(rd + traits::X0,tu.constant((uint32_t)((int32_t)sext<18>(imm)),32));
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,64); vm_base<ARCH>::gen_sync(tu, POST_SYNC,64);
gen_trap_check(tu); gen_trap_check(tu);
@ -2511,6 +2576,7 @@ private:
this->gen_raise_trap(tu, 0, 2); this->gen_raise_trap(tu, 0, 2);
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,65); vm_base<ARCH>::gen_sync(tu, POST_SYNC,65);
gen_trap_check(tu); gen_trap_check(tu);
@ -2532,6 +2598,7 @@ private:
tu.open_scope(); tu.open_scope();
this->gen_raise_trap(tu, 0, 2); this->gen_raise_trap(tu, 0, 2);
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,66); vm_base<ARCH>::gen_sync(tu, POST_SYNC,66);
gen_trap_check(tu); gen_trap_check(tu);
@ -2557,6 +2624,7 @@ private:
tu.open_scope(); tu.open_scope();
tu.store(rs1+ 8 + traits::X0,tu.lshr(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(shamt,8))); 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); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,67); vm_base<ARCH>::gen_sync(tu, POST_SYNC,67);
gen_trap_check(tu); gen_trap_check(tu);
@ -2587,6 +2655,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,68); vm_base<ARCH>::gen_sync(tu, POST_SYNC,68);
gen_trap_check(tu); gen_trap_check(tu);
@ -2612,6 +2681,7 @@ private:
tu.open_scope(); 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)); 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); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,69); vm_base<ARCH>::gen_sync(tu, POST_SYNC,69);
gen_trap_check(tu); gen_trap_check(tu);
@ -2637,6 +2707,7 @@ private:
tu.open_scope(); 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)); 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); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,70); vm_base<ARCH>::gen_sync(tu, POST_SYNC,70);
gen_trap_check(tu); gen_trap_check(tu);
@ -2662,6 +2733,7 @@ private:
tu.open_scope(); 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))); 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); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,71); vm_base<ARCH>::gen_sync(tu, POST_SYNC,71);
gen_trap_check(tu); gen_trap_check(tu);
@ -2687,6 +2759,7 @@ private:
tu.open_scope(); 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))); 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); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,72); vm_base<ARCH>::gen_sync(tu, POST_SYNC,72);
gen_trap_check(tu); gen_trap_check(tu);
@ -2712,6 +2785,7 @@ private:
tu.open_scope(); 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))); 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); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,73); vm_base<ARCH>::gen_sync(tu, POST_SYNC,73);
gen_trap_check(tu); gen_trap_check(tu);
@ -2738,6 +2812,7 @@ private:
tu.store(traits::NEXT_PC, PC_val_v); tu.store(traits::NEXT_PC, PC_val_v);
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2)); tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,74); vm_base<ARCH>::gen_sync(tu, POST_SYNC,74);
gen_trap_check(tu); gen_trap_check(tu);
@ -2767,6 +2842,7 @@ private:
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2)); tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
tu.close_scope(); tu.close_scope();
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,75); vm_base<ARCH>::gen_sync(tu, POST_SYNC,75);
gen_trap_check(tu); gen_trap_check(tu);
@ -2796,6 +2872,7 @@ private:
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2)); tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
tu.close_scope(); tu.close_scope();
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,76); vm_base<ARCH>::gen_sync(tu, POST_SYNC,76);
gen_trap_check(tu); gen_trap_check(tu);
@ -2828,6 +2905,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,77); vm_base<ARCH>::gen_sync(tu, POST_SYNC,77);
gen_trap_check(tu); gen_trap_check(tu);
@ -2859,6 +2937,7 @@ private:
tu.store(rd + traits::X0,tu.ext(tu.ext(tu.read_mem(traits::MEM, offs, 32),32,false),32,true)); 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); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,78); vm_base<ARCH>::gen_sync(tu, POST_SYNC,78);
gen_trap_check(tu); gen_trap_check(tu);
@ -2891,6 +2970,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,79); vm_base<ARCH>::gen_sync(tu, POST_SYNC,79);
gen_trap_check(tu); gen_trap_check(tu);
@ -2922,6 +3002,7 @@ private:
this->gen_raise_trap(tu, 0, 2); this->gen_raise_trap(tu, 0, 2);
} }
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,80); vm_base<ARCH>::gen_sync(tu, POST_SYNC,80);
gen_trap_check(tu); gen_trap_check(tu);
@ -2942,6 +3023,7 @@ private:
tu.open_scope(); tu.open_scope();
this->gen_raise_trap(tu, 0, 2); this->gen_raise_trap(tu, 0, 2);
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,81); vm_base<ARCH>::gen_sync(tu, POST_SYNC,81);
gen_trap_check(tu); gen_trap_check(tu);
@ -2974,6 +3056,7 @@ private:
} }
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,82); vm_base<ARCH>::gen_sync(tu, POST_SYNC,82);
gen_trap_check(tu); gen_trap_check(tu);
@ -3007,6 +3090,7 @@ private:
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2)); tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
} }
auto returnValue = std::make_tuple(BRANCH); auto returnValue = std::make_tuple(BRANCH);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,83); vm_base<ARCH>::gen_sync(tu, POST_SYNC,83);
gen_trap_check(tu); gen_trap_check(tu);
@ -3027,6 +3111,7 @@ private:
tu.open_scope(); tu.open_scope();
this->gen_raise_trap(tu, 0, 3); this->gen_raise_trap(tu, 0, 3);
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,84); vm_base<ARCH>::gen_sync(tu, POST_SYNC,84);
gen_trap_check(tu); gen_trap_check(tu);
@ -3058,6 +3143,7 @@ private:
tu.write_mem(traits::MEM, offs, tu.ext(tu.load(rs2+ traits::X0, 0),32,true)); tu.write_mem(traits::MEM, offs, tu.ext(tu.load(rs2+ traits::X0, 0),32,true));
} }
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,85); vm_base<ARCH>::gen_sync(tu, POST_SYNC,85);
gen_trap_check(tu); gen_trap_check(tu);
@ -3078,6 +3164,7 @@ private:
tu.open_scope(); tu.open_scope();
this->gen_raise_trap(tu, 0, 2); this->gen_raise_trap(tu, 0, 2);
auto returnValue = std::make_tuple(CONT); auto returnValue = std::make_tuple(CONT);
tu.close_scope(); tu.close_scope();
vm_base<ARCH>::gen_sync(tu, POST_SYNC,86); vm_base<ARCH>::gen_sync(tu, POST_SYNC,86);
gen_trap_check(tu); gen_trap_check(tu);