Compare commits

...

4 Commits

6 changed files with 1023 additions and 832 deletions

View File

@ -174,9 +174,17 @@ private:
* end opcode definitions
****************************************************************************/
continuation_e illegal_intruction(virt_addr_t &pc, code_word_t instr, jit_holder& jh ) {
x86::Compiler& cc = jh.cc;
cc.comment(fmt::format("illegal_intruction{:#x}:",pc.val).c_str());
this->gen_sync(jh, PRE_SYNC, instr_descr.size());
pc = pc + ((instr & 3) == 3 ? 4 : 2);
gen_instr_prologue(jh);
cc.comment("//behavior:");
gen_instr_epilogue(jh);
this->gen_sync(jh, POST_SYNC, instr_descr.size());
return BRANCH;
}
//decoding functionality
void populate_decoding_tree(decoding_tree_node* root){

View File

@ -99,16 +99,11 @@ protected:
std::tuple<continuation_e, BasicBlock *> gen_single_inst_behavior(virt_addr_t &, unsigned int &, BasicBlock *) override;
void gen_leave_behavior(BasicBlock *leave_blk) override;
void gen_raise_trap(uint16_t trap_id, uint16_t cause);
void gen_leave_trap(unsigned lvl);
void gen_wait(unsigned type);
void gen_trap_behavior(BasicBlock *) override;
void gen_trap_check(BasicBlock *bb);
void gen_instr_epilogue(BasicBlock *bb);
inline Value *gen_reg_load(unsigned i, unsigned level = 0) {
return this->builder.CreateLoad(this->get_typeptr(i), get_reg_ptr(i), false);
@ -162,20 +157,22 @@ private:
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
/* instruction ${idx}: ${instr.name} */
std::tuple<continuation_e, BasicBlock*> __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
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}<%}%>
}
bb->setName(fmt::format("${instr.name}_0x{:X}",pc.val));
this->gen_sync(PRE_SYNC,${idx});
auto cur_pc_val = this->gen_const(32,pc.val);
pc=pc+ ${instr.length/8};
this->gen_set_pc(pc, traits::NEXT_PC);
/*generate behavior*/
<%instr.behavior.eachLine{%>${it}
<%}%>
this->gen_trap_check(bb);
this->gen_instr_epilogue(bb);
this->gen_sync(POST_SYNC, ${idx});
this->builder.CreateBr(bb);
return returnValue;
@ -195,7 +192,7 @@ private:
pc = pc + ((instr & 3) == 3 ? 4 : 2);
this->gen_raise_trap(0, 2); // illegal instruction trap
this->gen_sync(iss::POST_SYNC, instr_descr.size());
this->gen_trap_check(this->leave_blk);
this->gen_instr_epilogue(this->leave_blk);
return std::make_tuple(BRANCH, nullptr);
}
//decoding functionality
@ -301,18 +298,21 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
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.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);
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::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)) };
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
auto *PC_val = this->gen_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8);
@ -320,12 +320,14 @@ template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
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) {
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)) };
this->builder.CreateCall(this->mod->getFunction("wait"), args);
}
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->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);
@ -338,7 +340,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_
this->builder.CreateRet(trap_addr_val);
}
template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(BasicBlock *bb) {
template <typename ARCH>
void vm_impl<ARCH>::gen_instr_epilogue(BasicBlock *bb) {
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(

View File

@ -292,7 +292,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
tu.store(traits::NEXT_PC, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
}
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {

View File

@ -80,7 +80,7 @@ public:
protected:
using super::get_ptr_for;
using super::get_reg;
using super::get_reg;
using super::get_reg_for;
using super::load_reg_from_mem;
using super::write_reg_to_mem;
@ -342,7 +342,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
(uint32_t)((int32_t)imm));
}
@ -388,7 +388,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
(uint32_t)(PC+(int32_t)imm));
}
@ -438,9 +438,9 @@ private:
gen_raise(jh, 0, 0);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
(uint32_t)(PC+ 4));
(uint32_t)(PC+4));
}
auto PC_val_v = (uint32_t)(PC+(int32_t)sext<21>(imm));
cc.mov(jh.next_pc, PC_val_v);
@ -505,9 +505,9 @@ private:
cc.jmp(label_merge);
cc.bind(label_else);
{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
(uint32_t)(PC+ 4));
(uint32_t)(PC+4));
}
auto PC_val_v = new_pc;
cc.mov(jh.next_pc, PC_val_v);
@ -914,7 +914,7 @@ private:
), 32, true);
auto res = gen_ext(jh,
gen_read_mem(jh, traits::MEM, load_address, 1), 8, false);
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh,
res, 32, true));
@ -967,7 +967,7 @@ private:
), 32, true);
auto res = gen_ext(jh,
gen_read_mem(jh, traits::MEM, load_address, 2), 16, false);
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh,
res, 32, true));
@ -1020,7 +1020,7 @@ private:
), 32, true);
auto res = gen_ext(jh,
gen_read_mem(jh, traits::MEM, load_address, 4), 32, false);
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh,
res, 32, true));
@ -1072,7 +1072,7 @@ private:
(gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm))
), 32, true);
auto res = gen_read_mem(jh, traits::MEM, load_address, 1);
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh,
res, 32, false));
@ -1124,7 +1124,7 @@ private:
(gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm))
), 32, true);
auto res = gen_read_mem(jh, traits::MEM, load_address, 2);
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh,
res, 32, false));
@ -1316,7 +1316,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh,
(gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int16_t)sext<12>(imm))
@ -1365,7 +1365,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
{
auto label_then = cc.newLabel();
auto label_merge = cc.newLabel();
@ -1373,10 +1373,10 @@ private:
cc.cmp(gen_ext(jh,
load_reg_from_mem(jh, traits::X0 + rs1), 32, true), (int16_t)sext<12>(imm));
cc.jl(label_then);
cc.mov(tmp_reg, 0);
cc.mov(tmp_reg,0);
cc.jmp(label_merge);
cc.bind(label_then);
cc.mov(tmp_reg, 1);
cc.mov(tmp_reg,1);
cc.bind(label_merge);
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh, tmp_reg
@ -1427,17 +1427,17 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
{
auto label_then = cc.newLabel();
auto label_merge = cc.newLabel();
auto tmp_reg = get_reg_for(jh, 1);
cc.cmp(load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm)));
cc.jb(label_then);
cc.mov(tmp_reg, 0);
cc.mov(tmp_reg,0);
cc.jmp(label_merge);
cc.bind(label_then);
cc.mov(tmp_reg, 1);
cc.mov(tmp_reg,1);
cc.bind(label_merge);
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh, tmp_reg
@ -1488,7 +1488,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_operation(jh, bxor, load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm)))
);
@ -1536,7 +1536,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_operation(jh, bor, load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm)))
);
@ -1584,7 +1584,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1), (uint32_t)((int16_t)sext<12>(imm)))
);
@ -1632,7 +1632,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_operation(jh, shl, load_reg_from_mem(jh, traits::X0 + rs1), shamt)
);
@ -1680,7 +1680,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_operation(jh, shr, load_reg_from_mem(jh, traits::X0 + rs1), shamt)
);
@ -1728,7 +1728,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh,
(gen_operation(jh, sar, gen_ext(jh,
@ -1778,7 +1778,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh,
(gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2))
@ -1827,7 +1827,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh,
(gen_operation(jh, sub, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2))
@ -1876,9 +1876,9 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh, gen_operation(jh, shl, load_reg_from_mem(jh, traits::X0 + rs1), (gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs2), (static_cast<uint32_t>(traits::XLEN)- 1))
gen_ext(jh, gen_operation(jh, shl, load_reg_from_mem(jh, traits::X0 + rs1), (gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs2), (static_cast<uint32_t>(traits::XLEN)-1))
))
, 32, false));
}
@ -1925,7 +1925,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
{
auto label_then = cc.newLabel();
auto label_merge = cc.newLabel();
@ -1934,10 +1934,10 @@ private:
load_reg_from_mem(jh, traits::X0 + rs1), 32, true), gen_ext(jh,
load_reg_from_mem(jh, traits::X0 + rs2), 32, true));
cc.jl(label_then);
cc.mov(tmp_reg, 0);
cc.mov(tmp_reg,0);
cc.jmp(label_merge);
cc.bind(label_then);
cc.mov(tmp_reg, 1);
cc.mov(tmp_reg,1);
cc.bind(label_merge);
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh, tmp_reg
@ -1988,17 +1988,17 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
{
auto label_then = cc.newLabel();
auto label_merge = cc.newLabel();
auto tmp_reg = get_reg_for(jh, 1);
cc.cmp(load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2));
cc.jb(label_then);
cc.mov(tmp_reg, 0);
cc.mov(tmp_reg,0);
cc.jmp(label_merge);
cc.bind(label_then);
cc.mov(tmp_reg, 1);
cc.mov(tmp_reg,1);
cc.bind(label_merge);
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh, tmp_reg
@ -2049,7 +2049,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_operation(jh, bxor, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2))
);
@ -2097,9 +2097,9 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh, gen_operation(jh, shr, load_reg_from_mem(jh, traits::X0 + rs1), (gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs2), (static_cast<uint32_t>(traits::XLEN)- 1))
gen_ext(jh, gen_operation(jh, shr, load_reg_from_mem(jh, traits::X0 + rs1), (gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs2), (static_cast<uint32_t>(traits::XLEN)-1))
))
, 32, false));
}
@ -2146,11 +2146,11 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh,
(gen_ext(jh, gen_operation(jh, sar, gen_ext(jh,
load_reg_from_mem(jh, traits::X0 + rs1), 32, true), (gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs2), (static_cast<uint32_t>(traits::XLEN)- 1))
load_reg_from_mem(jh, traits::X0 + rs1), 32, true), (gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs2), (static_cast<uint32_t>(traits::XLEN)-1))
))
, 32, true)), 32, true));
}
@ -2197,7 +2197,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_operation(jh, bor, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2))
);
@ -2245,7 +2245,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2))
);
@ -2291,7 +2291,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
gen_write_mem(jh, traits::FENCE, static_cast<uint32_t>(traits::fence), (uint8_t)pred<< 4|succ, 4);
gen_write_mem(jh, traits::FENCE, static_cast<uint32_t>(traits::fence), (uint8_t)pred<<4|succ, 4);
auto returnValue = CONT;
gen_instr_epilogue(jh);
@ -2475,7 +2475,7 @@ private:
}
else{
auto xrs1 = load_reg_from_mem(jh, traits::X0 + rs1);
if(rd!= 0){
if(rd!=0){
auto xrd = gen_read_mem(jh, traits::CSR, csr, 4);
gen_write_mem(jh, traits::CSR, csr, xrs1, 4);
cc.mov(get_ptr_for(jh, traits::X0+ rd),
@ -2529,11 +2529,11 @@ private:
else{
auto xrd = gen_read_mem(jh, traits::CSR, csr, 4);
auto xrs1 = load_reg_from_mem(jh, traits::X0 + rs1);
if(rs1!= 0){
if(rs1!=0){
gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, bor, xrd, xrs1)
, 4);
}
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
xrd);
}
@ -2582,11 +2582,11 @@ private:
else{
auto xrd = gen_read_mem(jh, traits::CSR, csr, 4);
auto xrs1 = load_reg_from_mem(jh, traits::X0 + rs1);
if(rs1!= 0){
if(rs1!=0){
gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, band, xrd, gen_operation(jh, bnot, xrs1))
, 4);
}
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
xrd);
}
@ -2635,7 +2635,7 @@ private:
else{
auto xrd = gen_read_mem(jh, traits::CSR, csr, 4);
gen_write_mem(jh, traits::CSR, csr, (uint32_t)zimm, 4);
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
xrd);
}
@ -2683,11 +2683,11 @@ private:
}
else{
auto xrd = gen_read_mem(jh, traits::CSR, csr, 4);
if(zimm!= 0){
if(zimm!=0){
gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, bor, xrd, (uint32_t)zimm)
, 4);
}
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
xrd);
}
@ -2735,11 +2735,11 @@ private:
}
else{
auto xrd = gen_read_mem(jh, traits::CSR, csr, 4);
if(zimm!= 0){
if(zimm!=0){
gen_write_mem(jh, traits::CSR, csr, gen_operation(jh, band, xrd, ~ ((uint32_t)zimm))
, 4);
}
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
xrd);
}
@ -2826,11 +2826,11 @@ private:
}
else{
auto res = gen_ext(jh,
(gen_operation(jh, imul,
(gen_operation(jh, imul, gen_ext(jh,
gen_ext(jh,
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true),
load_reg_from_mem(jh, traits::X0 + rs1), 32, true), 64, true), gen_ext(jh,
gen_ext(jh,
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 32, true), 64, true))
load_reg_from_mem(jh, traits::X0 + rs2), 32, true), 64, true))
), 64, true);
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
@ -3049,7 +3049,7 @@ private:
load_reg_from_mem(jh, traits::X0 + rs1), 32, false);
auto divisor = gen_ext(jh,
load_reg_from_mem(jh, traits::X0 + rs2), 32, false);
if(rd!= 0){
if(rd!=0){
auto label_merge = cc.newLabel();
cc.cmp(gen_operation(jh, ne, divisor, 0)
,0);
@ -3342,7 +3342,7 @@ private:
cc.comment("//behavior:");
/*generate behavior*/
if(imm){
cc.mov(get_ptr_for(jh, traits::X0+ rd+ 8),
cc.mov(get_ptr_for(jh, traits::X0+ rd+8),
gen_ext(jh,
(gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + 2), imm)
), 32, false));
@ -3389,9 +3389,9 @@ private:
cc.comment("//behavior:");
/*generate behavior*/
auto offs = gen_ext(jh,
(gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1+ 8), uimm)
(gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1+8), uimm)
), 32, false);
cc.mov(get_ptr_for(jh, traits::X0+ rd+ 8),
cc.mov(get_ptr_for(jh, traits::X0+ rd+8),
gen_ext(jh,
gen_ext(jh,
gen_read_mem(jh, traits::MEM, offs, 4), 32, false), 32, true));
@ -3434,10 +3434,10 @@ private:
cc.comment("//behavior:");
/*generate behavior*/
auto offs = gen_ext(jh,
(gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1+ 8), uimm)
(gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1+8), uimm)
), 32, false);
gen_write_mem(jh, traits::MEM, offs, gen_ext(jh,
load_reg_from_mem(jh, traits::X0 + rs2+ 8), 32, false), 4);
load_reg_from_mem(jh, traits::X0 + rs2+8), 32, false), 4);
auto returnValue = CONT;
gen_instr_epilogue(jh);
@ -3479,7 +3479,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rs1!= 0){
if(rs1!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rs1),
gen_ext(jh,
(gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rs1), (int8_t)sext<6>(imm))
@ -3558,7 +3558,7 @@ private:
cc.comment("//behavior:");
/*generate behavior*/
cc.mov(get_ptr_for(jh, traits::X0+ 1),
(uint32_t)(PC+ 2));
(uint32_t)(PC+2));
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm));
cc.mov(jh.next_pc, PC_val_v);
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
@ -3603,7 +3603,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
(uint32_t)((int8_t)sext<6>(imm)));
}
@ -3645,10 +3645,10 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
if(imm== 0||rd>=static_cast<uint32_t>(traits::RFS)){
if(imm==0||rd>=static_cast<uint32_t>(traits::RFS)){
gen_raise(jh, 0, 2);
}
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
(uint32_t)((int32_t)sext<18>(imm)));
}
@ -3770,8 +3770,8 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
cc.mov(get_ptr_for(jh, traits::X0+ rs1+ 8),
gen_operation(jh, shr, load_reg_from_mem(jh, traits::X0 + rs1+ 8), shamt)
cc.mov(get_ptr_for(jh, traits::X0+ rs1+8),
gen_operation(jh, shr, load_reg_from_mem(jh, traits::X0 + rs1+8), shamt)
);
auto returnValue = CONT;
@ -3811,18 +3811,18 @@ private:
cc.comment("//behavior:");
/*generate behavior*/
if(shamt){
cc.mov(get_ptr_for(jh, traits::X0+ rs1+ 8),
cc.mov(get_ptr_for(jh, traits::X0+ rs1+8),
gen_ext(jh,
(gen_operation(jh, sar, (gen_ext(jh,
load_reg_from_mem(jh, traits::X0 + rs1+ 8), 32, false)), shamt)
load_reg_from_mem(jh, traits::X0 + rs1+8), 32, false)), shamt)
), 32, true));
}
else{
if(static_cast<uint32_t>(traits::XLEN)== 128){
cc.mov(get_ptr_for(jh, traits::X0+ rs1+ 8),
if(static_cast<uint32_t>(traits::XLEN)==128){
cc.mov(get_ptr_for(jh, traits::X0+ rs1+8),
gen_ext(jh,
(gen_operation(jh, sar, (gen_ext(jh,
load_reg_from_mem(jh, traits::X0 + rs1+ 8), 32, false)), 64)
load_reg_from_mem(jh, traits::X0 + rs1+8), 32, false)), 64)
), 32, true));
}
}
@ -3863,9 +3863,9 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
cc.mov(get_ptr_for(jh, traits::X0+ rs1+ 8),
cc.mov(get_ptr_for(jh, traits::X0+ rs1+8),
gen_ext(jh,
(gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1+ 8), (int8_t)sext<6>(imm))
(gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1+8), (int8_t)sext<6>(imm))
), 32, true));
auto returnValue = CONT;
@ -3904,9 +3904,9 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
cc.mov(get_ptr_for(jh, traits::X0+ rd+ 8),
cc.mov(get_ptr_for(jh, traits::X0+ rd+8),
gen_ext(jh,
(gen_operation(jh, sub, load_reg_from_mem(jh, traits::X0 + rd+ 8), load_reg_from_mem(jh, traits::X0 + rs2+ 8))
(gen_operation(jh, sub, load_reg_from_mem(jh, traits::X0 + rd+8), load_reg_from_mem(jh, traits::X0 + rs2+8))
), 32, true));
auto returnValue = CONT;
@ -3945,8 +3945,8 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
cc.mov(get_ptr_for(jh, traits::X0+ rd+ 8),
gen_operation(jh, bxor, load_reg_from_mem(jh, traits::X0 + rd+ 8), load_reg_from_mem(jh, traits::X0 + rs2+ 8))
cc.mov(get_ptr_for(jh, traits::X0+ rd+8),
gen_operation(jh, bxor, load_reg_from_mem(jh, traits::X0 + rd+8), load_reg_from_mem(jh, traits::X0 + rs2+8))
);
auto returnValue = CONT;
@ -3985,8 +3985,8 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
cc.mov(get_ptr_for(jh, traits::X0+ rd+ 8),
gen_operation(jh, bor, load_reg_from_mem(jh, traits::X0 + rd+ 8), load_reg_from_mem(jh, traits::X0 + rs2+ 8))
cc.mov(get_ptr_for(jh, traits::X0+ rd+8),
gen_operation(jh, bor, load_reg_from_mem(jh, traits::X0 + rd+8), load_reg_from_mem(jh, traits::X0 + rs2+8))
);
auto returnValue = CONT;
@ -4025,8 +4025,8 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
cc.mov(get_ptr_for(jh, traits::X0+ rd+ 8),
gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rd+ 8), load_reg_from_mem(jh, traits::X0 + rs2+ 8))
cc.mov(get_ptr_for(jh, traits::X0+ rd+8),
gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rd+8), load_reg_from_mem(jh, traits::X0 + rs2+8))
);
auto returnValue = CONT;
@ -4105,7 +4105,7 @@ private:
cc.comment("//behavior:");
/*generate behavior*/
auto label_merge = cc.newLabel();
cc.cmp(gen_operation(jh, eq, load_reg_from_mem(jh, traits::X0 + rs1+ 8), 0)
cc.cmp(gen_operation(jh, eq, load_reg_from_mem(jh, traits::X0 + rs1+8), 0)
,0);
cc.je(label_merge);
{
@ -4152,7 +4152,7 @@ private:
cc.comment("//behavior:");
/*generate behavior*/
auto label_merge = cc.newLabel();
cc.cmp(gen_operation(jh, ne, load_reg_from_mem(jh, traits::X0 + rs1+ 8), 0)
cc.cmp(gen_operation(jh, ne, load_reg_from_mem(jh, traits::X0 + rs1+8), 0)
,0);
cc.je(label_merge);
{
@ -4202,7 +4202,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rs1!= 0){
if(rs1!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rs1),
gen_operation(jh, shl, load_reg_from_mem(jh, traits::X0 + rs1), nzuimm)
);
@ -4245,7 +4245,7 @@ private:
gen_instr_prologue(jh);
cc.comment("//behavior:");
/*generate behavior*/
if(rd>=static_cast<uint32_t>(traits::RFS)||rd== 0){
if(rd>=static_cast<uint32_t>(traits::RFS)||rd==0){
gen_raise(jh, 0, 2);
}
else{
@ -4298,7 +4298,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
load_reg_from_mem(jh, traits::X0 + rs2));
}
@ -4340,7 +4340,7 @@ private:
cc.comment("//behavior:");
/*generate behavior*/
if(rs1&&rs1<static_cast<uint32_t>(traits::RFS)){
auto PC_val_v = gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1%static_cast<uint32_t>(traits::RFS)), ~ 0x1)
auto PC_val_v = gen_operation(jh, band, load_reg_from_mem(jh, traits::X0 + rs1%static_cast<uint32_t>(traits::RFS)), ~ 1)
;
cc.mov(jh.next_pc, PC_val_v);
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
@ -4424,7 +4424,7 @@ private:
gen_raise(jh, 0, 2);
}
else{
if(rd!= 0){
if(rd!=0){
cc.mov(get_ptr_for(jh, traits::X0+ rd),
gen_ext(jh,
(gen_operation(jh, add, load_reg_from_mem(jh, traits::X0 + rd), load_reg_from_mem(jh, traits::X0 + rs2))
@ -4473,8 +4473,8 @@ private:
else{
auto new_pc = load_reg_from_mem(jh, traits::X0 + rs1);
cc.mov(get_ptr_for(jh, traits::X0+ 1),
(uint32_t)(PC+ 2));
auto PC_val_v = gen_operation(jh, band, new_pc, ~ 0x1)
(uint32_t)(PC+2));
auto PC_val_v = gen_operation(jh, band, new_pc, ~ 1)
;
cc.mov(jh.next_pc, PC_val_v);
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
@ -4607,7 +4607,14 @@ private:
* end opcode definitions
****************************************************************************/
continuation_e illegal_intruction(virt_addr_t &pc, code_word_t instr, jit_holder& jh ) {
x86::Compiler& cc = jh.cc;
cc.comment(fmt::format("illegal_intruction{:#x}:",pc.val).c_str());
this->gen_sync(jh, PRE_SYNC, instr_descr.size());
pc = pc + ((instr & 3) == 3 ? 4 : 2);
gen_instr_prologue(jh);
cc.comment("//behavior:");
gen_instr_epilogue(jh);
this->gen_sync(jh, POST_SYNC, instr_descr.size());
return BRANCH;
}
//decoding functionality

File diff suppressed because it is too large Load Diff

View File

@ -349,7 +349,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.constant((uint32_t)((int32_t)imm),32));
}
@ -384,7 +384,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.constant((uint32_t)(PC+(int32_t)imm),32));
}
@ -422,9 +422,9 @@ private:
if(imm%static_cast<uint32_t>(traits:: INSTR_ALIGNMENT)){ this->gen_raise_trap(tu, 0, 0);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.constant((uint32_t)(PC+ 4),32));
tu.constant((uint32_t)(PC+4),32));
}
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int32_t)sext<21>(imm)),32);
tu.store(traits::NEXT_PC, PC_val_v);
@ -473,9 +473,9 @@ private:
tu.constant(static_cast<uint32_t>(traits:: INSTR_ALIGNMENT),32)));
this->gen_raise_trap(tu, 0, 0);
tu.open_else();
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.constant((uint32_t)(PC+ 4),32));
tu.constant((uint32_t)(PC+4),32));
}
auto PC_val_v = tu.assignment("PC_val", new_pc,32);
tu.store(traits::NEXT_PC, PC_val_v);
@ -775,7 +775,7 @@ private:
tu.load(rs1+ traits::X0, 0),
tu.constant((int16_t)sext<12>(imm),16))),32,false),32);
auto res = tu.assignment(tu.ext(tu.read_mem(traits::MEM, load_address, 8),8,true),8);
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext(res,32,false));
}
@ -815,7 +815,7 @@ private:
tu.load(rs1+ traits::X0, 0),
tu.constant((int16_t)sext<12>(imm),16))),32,false),32);
auto res = tu.assignment(tu.ext(tu.read_mem(traits::MEM, load_address, 16),16,true),16);
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext(res,32,false));
}
@ -855,7 +855,7 @@ private:
tu.load(rs1+ traits::X0, 0),
tu.constant((int16_t)sext<12>(imm),16))),32,false),32);
auto res = tu.assignment(tu.ext(tu.read_mem(traits::MEM, load_address, 32),32,true),32);
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext(res,32,false));
}
@ -895,7 +895,7 @@ private:
tu.load(rs1+ traits::X0, 0),
tu.constant((int16_t)sext<12>(imm),16))),32,false),32);
auto res = tu.assignment(tu.read_mem(traits::MEM, load_address, 8),8);
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext(res,32,false));
}
@ -935,7 +935,7 @@ private:
tu.load(rs1+ traits::X0, 0),
tu.constant((int16_t)sext<12>(imm),16))),32,false),32);
auto res = tu.assignment(tu.read_mem(traits::MEM, load_address, 16),16);
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext(res,32,false));
}
@ -1079,7 +1079,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext((tu.add(
tu.load(rs1+ traits::X0, 0),
@ -1117,11 +1117,11 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.conditionalAssignment((tu.icmp(ICmpInst::ICMP_SLT,
tu.ext(tu.load(rs1+ traits::X0, 0),32,true),
tu.constant((int16_t)sext<12>(imm),16))), tu.constant( 1,8),tu.constant( 0,8)));
tu.constant((int16_t)sext<12>(imm),16))), tu.constant(1,8),tu.constant(0,8)));
}
}
auto returnValue = std::make_tuple(CONT);
@ -1155,11 +1155,11 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.conditionalAssignment((tu.icmp(ICmpInst::ICMP_ULT,
tu.load(rs1+ traits::X0, 0),
tu.constant((uint32_t)((int16_t)sext<12>(imm)),32))), tu.constant( 1,8),tu.constant( 0,8)));
tu.constant((uint32_t)((int16_t)sext<12>(imm)),32))), tu.constant(1,8),tu.constant(0,8)));
}
}
auto returnValue = std::make_tuple(CONT);
@ -1193,7 +1193,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.bitwise_xor(
tu.load(rs1+ traits::X0, 0),
@ -1231,7 +1231,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.bitwise_or(
tu.load(rs1+ traits::X0, 0),
@ -1269,7 +1269,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.bitwise_and(
tu.load(rs1+ traits::X0, 0),
@ -1307,7 +1307,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.shl(
tu.load(rs1+ traits::X0, 0),
@ -1345,7 +1345,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.lshr(
tu.load(rs1+ traits::X0, 0),
@ -1383,7 +1383,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext((tu.ashr(
tu.ext(tu.load(rs1+ traits::X0, 0),32,true),
@ -1421,7 +1421,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext((tu.add(
tu.load(rs1+ traits::X0, 0),
@ -1459,7 +1459,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext((tu.sub(
tu.load(rs1+ traits::X0, 0),
@ -1497,13 +1497,13 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.shl(
tu.load(rs1+ traits::X0, 0),
(tu.bitwise_and(
tu.load(rs2+ traits::X0, 0),
tu.constant((static_cast<uint32_t>(traits:: XLEN)- 1),64)))));
tu.constant((static_cast<uint32_t>(traits:: XLEN)-1),64)))));
}
}
auto returnValue = std::make_tuple(CONT);
@ -1537,11 +1537,11 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_SLT,
tu.ext(tu.load(rs1+ traits::X0, 0),32,true),
tu.ext(tu.load(rs2+ traits::X0, 0),32,true)), tu.constant( 1,8),tu.constant( 0,8)));
tu.ext(tu.load(rs2+ traits::X0, 0),32,true)), tu.constant(1,8),tu.constant(0,8)));
}
}
auto returnValue = std::make_tuple(CONT);
@ -1575,11 +1575,11 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_ULT,
tu.load(rs1+ traits::X0, 0),
tu.load(rs2+ traits::X0, 0)), tu.constant( 1,8),tu.constant( 0,8)));
tu.load(rs2+ traits::X0, 0)), tu.constant(1,8),tu.constant(0,8)));
}
}
auto returnValue = std::make_tuple(CONT);
@ -1613,7 +1613,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.bitwise_xor(
tu.load(rs1+ traits::X0, 0),
@ -1651,13 +1651,13 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.lshr(
tu.load(rs1+ traits::X0, 0),
(tu.bitwise_and(
tu.load(rs2+ traits::X0, 0),
tu.constant((static_cast<uint32_t>(traits:: XLEN)- 1),64)))));
tu.constant((static_cast<uint32_t>(traits:: XLEN)-1),64)))));
}
}
auto returnValue = std::make_tuple(CONT);
@ -1691,13 +1691,13 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext((tu.ashr(
tu.ext(tu.load(rs1+ traits::X0, 0),32,true),
(tu.bitwise_and(
tu.load(rs2+ traits::X0, 0),
tu.constant((static_cast<uint32_t>(traits:: XLEN)- 1),64))))),32,false));
tu.constant((static_cast<uint32_t>(traits:: XLEN)-1),64))))),32,false));
}
}
auto returnValue = std::make_tuple(CONT);
@ -1731,7 +1731,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.bitwise_or(
tu.load(rs1+ traits::X0, 0),
@ -1769,7 +1769,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.bitwise_and(
tu.load(rs1+ traits::X0, 0),
@ -1805,7 +1805,7 @@ private:
pc=pc+ 4;
gen_set_pc(tu, pc, traits::NEXT_PC);
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);
tu.close_scope();
@ -1926,7 +1926,7 @@ private:
}
else{
auto xrs1 = tu.assignment(tu.load(rs1+ traits::X0, 0),32);
if(rd!= 0){ auto xrd = tu.assignment(tu.read_mem(traits::CSR, csr, 32),32);
if(rd!=0){ auto xrd = tu.assignment(tu.read_mem(traits::CSR, csr, 32),32);
tu.write_mem(traits::CSR, csr, xrs1);
tu.store(rd + traits::X0,
xrd);
@ -1968,12 +1968,12 @@ private:
else{
auto xrd = tu.assignment(tu.read_mem(traits::CSR, csr, 32),32);
auto xrs1 = tu.assignment(tu.load(rs1+ traits::X0, 0),32);
if(rs1!= 0) {
if(rs1!=0) {
tu.write_mem(traits::CSR, csr, tu.bitwise_or(
xrd,
xrs1));
}
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
xrd);
}
@ -2011,12 +2011,12 @@ private:
else{
auto xrd = tu.assignment(tu.read_mem(traits::CSR, csr, 32),32);
auto xrs1 = tu.assignment(tu.load(rs1+ traits::X0, 0),32);
if(rs1!= 0) {
if(rs1!=0) {
tu.write_mem(traits::CSR, csr, tu.bitwise_and(
xrd,
tu.logical_neg(xrs1)));
}
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
xrd);
}
@ -2054,7 +2054,7 @@ private:
else{
auto xrd = tu.assignment(tu.read_mem(traits::CSR, csr, 32),32);
tu.write_mem(traits::CSR, csr, tu.constant((uint32_t)zimm,32));
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
xrd);
}
@ -2091,12 +2091,12 @@ private:
}
else{
auto xrd = tu.assignment(tu.read_mem(traits::CSR, csr, 32),32);
if(zimm!= 0) {
if(zimm!=0) {
tu.write_mem(traits::CSR, csr, tu.bitwise_or(
xrd,
tu.constant((uint32_t)zimm,32)));
}
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
xrd);
}
@ -2133,12 +2133,12 @@ private:
}
else{
auto xrd = tu.assignment(tu.read_mem(traits::CSR, csr, 32),32);
if(zimm!= 0) {
if(zimm!=0) {
tu.write_mem(traits::CSR, csr, tu.bitwise_and(
xrd,
tu.constant(~ ((uint32_t)zimm),32)));
}
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
xrd);
}
@ -2171,7 +2171,7 @@ private:
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
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(FLUSH);
tu.close_scope();
gen_trap_check(tu);
@ -2366,9 +2366,9 @@ private:
else{
auto dividend = tu.assignment(tu.ext(tu.load(rs1+ traits::X0, 0),32,true),32);
auto divisor = tu.assignment(tu.ext(tu.load(rs2+ traits::X0, 0),32,true),32);
if(rd!= 0){ tu.open_if(tu.icmp(ICmpInst::ICMP_NE,
if(rd!=0){ tu.open_if(tu.icmp(ICmpInst::ICMP_NE,
divisor,
tu.constant( 0,8)));
tu.constant(0,8)));
auto MMIN = tu.assignment(tu.constant(((uint32_t)1)<<(static_cast<uint32_t>(traits:: XLEN)-1),32),32);
tu.open_if(tu.logical_and(
tu.icmp(ICmpInst::ICMP_EQ,
@ -2424,7 +2424,7 @@ private:
else{
tu.open_if(tu.icmp(ICmpInst::ICMP_NE,
tu.load(rs2+ traits::X0, 0),
tu.constant( 0,8)));
tu.constant(0,8)));
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext((tu.udiv(
@ -2471,7 +2471,7 @@ private:
else{
tu.open_if(tu.icmp(ICmpInst::ICMP_NE,
tu.load(rs2+ traits::X0, 0),
tu.constant( 0,8)));
tu.constant(0,8)));
auto MMIN = tu.assignment(tu.constant((uint32_t)1<<(static_cast<uint32_t>(traits:: XLEN)-1),32),32);
tu.open_if(tu.logical_and(
tu.icmp(ICmpInst::ICMP_EQ,
@ -2482,7 +2482,7 @@ private:
tu.constant(- 1,8))));
if(rd!=0) {
tu.store(rd + traits::X0,
tu.constant( 0,8));
tu.constant(0,8));
}
tu.open_else();
if(rd!=0) {
@ -2532,7 +2532,7 @@ private:
else{
tu.open_if(tu.icmp(ICmpInst::ICMP_NE,
tu.load(rs2+ traits::X0, 0),
tu.constant( 0,8)));
tu.constant(0,8)));
if(rd!=0) {
tu.store(rd + traits::X0,
tu.urem(
@ -2573,7 +2573,7 @@ private:
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
if(imm) {
tu.store(rd+ 8 + traits::X0,
tu.store(rd+8 + traits::X0,
tu.ext((tu.add(
tu.load(2+ traits::X0, 0),
tu.constant(imm,16))),32,false));
@ -2609,9 +2609,9 @@ private:
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
auto offs = tu.assignment(tu.ext((tu.add(
tu.load(rs1+ 8+ traits::X0, 0),
tu.load(rs1+8+ traits::X0, 0),
tu.constant(uimm,8))),32,false),32);
tu.store(rd+ 8 + traits::X0,
tu.store(rd+8 + traits::X0,
tu.ext(tu.ext(tu.read_mem(traits::MEM, offs, 32),32,true),32,false));
auto returnValue = std::make_tuple(CONT);
@ -2641,9 +2641,9 @@ private:
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
auto offs = tu.assignment(tu.ext((tu.add(
tu.load(rs1+ 8+ traits::X0, 0),
tu.load(rs1+8+ traits::X0, 0),
tu.constant(uimm,8))),32,false),32);
tu.write_mem(traits::MEM, offs, tu.ext(tu.load(rs2+ 8+ traits::X0, 0),32,false));
tu.write_mem(traits::MEM, offs, tu.ext(tu.load(rs2+8+ traits::X0, 0),32,false));
auto returnValue = std::make_tuple(CONT);
tu.close_scope();
@ -2674,7 +2674,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rs1!= 0) {
if(rs1!=0) {
tu.store(rs1 + traits::X0,
tu.ext((tu.add(
tu.load(rs1+ traits::X0, 0),
@ -2729,7 +2729,7 @@ private:
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
tu.store(1 + traits::X0,
tu.constant((uint32_t)(PC+ 2),32));
tu.constant((uint32_t)(PC+2),32));
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int16_t)sext<12>(imm)),32);
tu.store(traits::NEXT_PC, PC_val_v);
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
@ -2763,7 +2763,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.constant((uint32_t)((int8_t)sext<6>(imm)),32));
}
@ -2794,10 +2794,10 @@ private:
pc=pc+ 2;
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
if(imm== 0||rd>=static_cast<uint32_t>(traits:: RFS)) {
if(imm==0||rd>=static_cast<uint32_t>(traits:: RFS)) {
this->gen_raise_trap(tu, 0, 2);
}
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.constant((uint32_t)((int32_t)sext<18>(imm)),32));
}
@ -2884,9 +2884,9 @@ private:
pc=pc+ 2;
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
tu.store(rs1+ 8 + traits::X0,
tu.store(rs1+8 + traits::X0,
tu.lshr(
tu.load(rs1+ 8+ traits::X0, 0),
tu.load(rs1+8+ traits::X0, 0),
tu.constant(shamt,8)));
auto returnValue = std::make_tuple(CONT);
@ -2914,16 +2914,16 @@ private:
pc=pc+ 2;
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
if(shamt){ tu.store(rs1+ 8 + traits::X0,
if(shamt){ tu.store(rs1+8 + traits::X0,
tu.ext((tu.ashr(
(tu.ext(tu.load(rs1+ 8+ traits::X0, 0),32,true)),
(tu.ext(tu.load(rs1+8+ traits::X0, 0),32,true)),
tu.constant(shamt,8))),32,false));
}
else{
if(static_cast<uint32_t>(traits:: XLEN)== 128){ tu.store(rs1+ 8 + traits::X0,
if(static_cast<uint32_t>(traits:: XLEN)==128){ tu.store(rs1+8 + traits::X0,
tu.ext((tu.ashr(
(tu.ext(tu.load(rs1+ 8+ traits::X0, 0),32,true)),
tu.constant( 64,8))),32,false));
(tu.ext(tu.load(rs1+8+ traits::X0, 0),32,true)),
tu.constant(64,8))),32,false));
}
}
auto returnValue = std::make_tuple(CONT);
@ -2952,9 +2952,9 @@ private:
pc=pc+ 2;
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
tu.store(rs1+ 8 + traits::X0,
tu.store(rs1+8 + traits::X0,
tu.ext((tu.bitwise_and(
tu.load(rs1+ 8+ traits::X0, 0),
tu.load(rs1+8+ traits::X0, 0),
tu.constant((int8_t)sext<6>(imm),8))),32,false));
auto returnValue = std::make_tuple(CONT);
@ -2982,10 +2982,10 @@ private:
pc=pc+ 2;
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
tu.store(rd+ 8 + traits::X0,
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,false));
tu.load(rd+8+ traits::X0, 0),
tu.load(rs2+8+ traits::X0, 0))),32,false));
auto returnValue = std::make_tuple(CONT);
tu.close_scope();
@ -3012,10 +3012,10 @@ private:
pc=pc+ 2;
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
tu.store(rd+ 8 + traits::X0,
tu.store(rd+8 + traits::X0,
tu.bitwise_xor(
tu.load(rd+ 8+ traits::X0, 0),
tu.load(rs2+ 8+ traits::X0, 0)));
tu.load(rd+8+ traits::X0, 0),
tu.load(rs2+8+ traits::X0, 0)));
auto returnValue = std::make_tuple(CONT);
tu.close_scope();
@ -3042,10 +3042,10 @@ private:
pc=pc+ 2;
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
tu.store(rd+ 8 + traits::X0,
tu.store(rd+8 + traits::X0,
tu.bitwise_or(
tu.load(rd+ 8+ traits::X0, 0),
tu.load(rs2+ 8+ traits::X0, 0)));
tu.load(rd+8+ traits::X0, 0),
tu.load(rs2+8+ traits::X0, 0)));
auto returnValue = std::make_tuple(CONT);
tu.close_scope();
@ -3072,10 +3072,10 @@ private:
pc=pc+ 2;
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
tu.store(rd+ 8 + traits::X0,
tu.store(rd+8 + traits::X0,
tu.bitwise_and(
tu.load(rd+ 8+ traits::X0, 0),
tu.load(rs2+ 8+ traits::X0, 0)));
tu.load(rd+8+ traits::X0, 0),
tu.load(rs2+8+ traits::X0, 0)));
auto returnValue = std::make_tuple(CONT);
tu.close_scope();
@ -3131,8 +3131,8 @@ private:
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
tu.open_if(tu.icmp(ICmpInst::ICMP_EQ,
tu.load(rs1+ 8+ traits::X0, 0),
tu.constant( 0,8)));
tu.load(rs1+8+ traits::X0, 0),
tu.constant(0,8)));
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int16_t)sext<9>(imm)),32);
tu.store(traits::NEXT_PC, PC_val_v);
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
@ -3164,8 +3164,8 @@ private:
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
tu.open_if(tu.icmp(ICmpInst::ICMP_NE,
tu.load(rs1+ 8+ traits::X0, 0),
tu.constant( 0,8)));
tu.load(rs1+8+ traits::X0, 0),
tu.constant(0,8)));
auto PC_val_v = tu.assignment("PC_val", (uint32_t)(PC+(int16_t)sext<9>(imm)),32);
tu.store(traits::NEXT_PC, PC_val_v);
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
@ -3200,7 +3200,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rs1!= 0) {
if(rs1!=0) {
tu.store(rs1 + traits::X0,
tu.shl(
tu.load(rs1+ traits::X0, 0),
@ -3233,7 +3233,7 @@ private:
pc=pc+ 2;
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
if(rd>=static_cast<uint32_t>(traits:: RFS)||rd== 0) {
if(rd>=static_cast<uint32_t>(traits:: RFS)||rd==0) {
this->gen_raise_trap(tu, 0, 2);
}
else{
@ -3273,7 +3273,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.load(rs2+ traits::X0, 0));
}
@ -3303,10 +3303,9 @@ private:
pc=pc+ 2;
gen_set_pc(tu, pc, traits::NEXT_PC);
tu.open_scope();
if(rs1&&rs1<static_cast<uint32_t>(traits:: RFS)) {
auto PC_val_v = tu.assignment("PC_val", tu.bitwise_and(
if(rs1&&rs1<static_cast<uint32_t>(traits:: RFS)){ auto PC_val_v = tu.assignment("PC_val", tu.bitwise_and(
tu.load(rs1%static_cast<uint32_t>(traits:: RFS)+ traits::X0, 0),
tu.constant(~ 0x1,8)),32);
tu.constant(~ 1,32)),32);
tu.store(traits::NEXT_PC, PC_val_v);
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
}
@ -3365,7 +3364,7 @@ private:
this->gen_raise_trap(tu, 0, 2);
}
else{
if(rd!= 0) {
if(rd!=0) {
tu.store(rd + traits::X0,
tu.ext((tu.add(
tu.load(rd+ traits::X0, 0),
@ -3403,10 +3402,10 @@ private:
else{
auto new_pc = tu.assignment(tu.load(rs1+ traits::X0, 0),32);
tu.store(1 + traits::X0,
tu.constant((uint32_t)(PC+ 2),32));
tu.constant((uint32_t)(PC+2),32));
auto PC_val_v = tu.assignment("PC_val", tu.bitwise_and(
new_pc,
tu.constant(~ 0x1,8)),32);
tu.constant(~ 1,32)),32);
tu.store(traits::NEXT_PC, PC_val_v);
tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
}
@ -3612,7 +3611,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
tu.store(traits::NEXT_PC, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
}
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {