checking: working
This commit is contained in:
parent
b25b7848c6
commit
602bc6e06a
@ -79,21 +79,36 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
using vm_base<ARCH>::get_reg_ptr;
|
||||
using super::get_ptr_for;
|
||||
using super::get_reg;
|
||||
using super::get_reg_for;
|
||||
using super::load_reg_from_mem;
|
||||
using super::write_reg_to_mem;
|
||||
using super::gen_ext;
|
||||
using super::gen_read_mem;
|
||||
using super::gen_write_mem;
|
||||
using super::gen_wait;
|
||||
using super::gen_leave;
|
||||
using super::gen_operation;
|
||||
|
||||
using this_class = vm_impl<ARCH>;
|
||||
using compile_func = continuation_e (this_class::*)(virt_addr_t&, code_word_t, jit_holder&);
|
||||
|
||||
continuation_e gen_single_inst_behavior(virt_addr_t&, unsigned int &, jit_holder&) override;
|
||||
void gen_block_prologue(jit_holder& jh) override;
|
||||
void gen_block_epilogue(jit_holder& jh) override;
|
||||
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
||||
|
||||
void gen_instr_prologue(jit_holder& jh, addr_t pc);
|
||||
void gen_instr_epilogue(jit_holder& jh);
|
||||
inline void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause);
|
||||
|
||||
template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
|
||||
inline S sext(U from) {
|
||||
auto mask = (1ULL<<W) - 1;
|
||||
auto sign_mask = 1ULL<<(W-1);
|
||||
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
||||
}
|
||||
#include <vm/asmjit/helper_func.h>
|
||||
|
||||
private:
|
||||
/****************************************************************************
|
||||
* start opcode definitions
|
||||
@ -326,7 +341,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
(uint32_t)((int32_t)imm));
|
||||
}
|
||||
}
|
||||
@ -370,7 +385,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
(uint32_t)(PC+(int32_t)imm));
|
||||
}
|
||||
}
|
||||
@ -418,12 +433,12 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
(uint32_t)(PC+ 4));
|
||||
}
|
||||
auto PC_val_v = (uint32_t)(PC+(int32_t)sext<21>(imm));
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
}
|
||||
auto returnValue = BRANCH;
|
||||
@ -486,12 +501,12 @@ private:
|
||||
cc.bind(label_else);
|
||||
{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
(uint32_t)(PC+ 4));
|
||||
}
|
||||
auto PC_val_v = new_pc;
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
cc.bind(label_merge);
|
||||
}
|
||||
@ -547,7 +562,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
}
|
||||
cc.bind(label_merge);
|
||||
@ -604,7 +619,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
}
|
||||
cc.bind(label_merge);
|
||||
@ -663,7 +678,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
}
|
||||
cc.bind(label_merge);
|
||||
@ -722,7 +737,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
}
|
||||
cc.bind(label_merge);
|
||||
@ -779,7 +794,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
}
|
||||
cc.bind(label_merge);
|
||||
@ -836,7 +851,7 @@ private:
|
||||
else{
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<13>(imm));
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
}
|
||||
cc.bind(label_merge);
|
||||
@ -888,7 +903,7 @@ private:
|
||||
auto res = gen_ext(jh,
|
||||
gen_read_mem(jh, traits::MEM, load_address, 1), 8, false);
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
res, 32, true));
|
||||
}
|
||||
@ -940,7 +955,7 @@ private:
|
||||
auto res = gen_ext(jh,
|
||||
gen_read_mem(jh, traits::MEM, load_address, 2), 16, false);
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
res, 32, true));
|
||||
}
|
||||
@ -992,7 +1007,7 @@ private:
|
||||
auto res = gen_ext(jh,
|
||||
gen_read_mem(jh, traits::MEM, load_address, 4), 32, false);
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
res, 32, true));
|
||||
}
|
||||
@ -1043,7 +1058,7 @@ private:
|
||||
), 32, true);
|
||||
auto res = gen_read_mem(jh, traits::MEM, load_address, 1);
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
res, 32, false));
|
||||
}
|
||||
@ -1094,7 +1109,7 @@ private:
|
||||
), 32, true);
|
||||
auto res = gen_read_mem(jh, traits::MEM, load_address, 2);
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
res, 32, false));
|
||||
}
|
||||
@ -1281,7 +1296,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, add,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int16_t)sext<12>(imm), 64, true))
|
||||
@ -1341,7 +1356,7 @@ private:
|
||||
cc.bind(label_then);
|
||||
cc.mov(tmp_reg, 1);
|
||||
cc.bind(label_merge);
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh, tmp_reg
|
||||
, 32, false)
|
||||
);
|
||||
@ -1400,7 +1415,7 @@ private:
|
||||
cc.bind(label_then);
|
||||
cc.mov(tmp_reg, 1);
|
||||
cc.bind(label_merge);
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh, tmp_reg
|
||||
, 32, false)
|
||||
);
|
||||
@ -1448,7 +1463,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
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)))
|
||||
);
|
||||
@ -1495,7 +1510,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
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)))
|
||||
);
|
||||
@ -1542,7 +1557,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
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)))
|
||||
);
|
||||
@ -1589,7 +1604,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_operation(jh, shl,
|
||||
load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, shamt, 32, false))
|
||||
);
|
||||
@ -1636,7 +1651,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_operation(jh, shr,
|
||||
load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, shamt, 32, false))
|
||||
);
|
||||
@ -1683,7 +1698,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, sar,
|
||||
gen_ext(jh,
|
||||
@ -1732,7 +1747,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, add,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false))
|
||||
@ -1780,7 +1795,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, sub,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false))
|
||||
@ -1828,7 +1843,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh, gen_operation(jh, shl,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), (gen_operation(jh, band,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false), (static_cast<uint32_t>(traits::XLEN)- 1))
|
||||
@ -1890,7 +1905,7 @@ private:
|
||||
cc.bind(label_then);
|
||||
cc.mov(tmp_reg, 1);
|
||||
cc.bind(label_merge);
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh, tmp_reg
|
||||
, 32, false)
|
||||
);
|
||||
@ -1949,7 +1964,7 @@ private:
|
||||
cc.bind(label_then);
|
||||
cc.mov(tmp_reg, 1);
|
||||
cc.bind(label_merge);
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh, tmp_reg
|
||||
, 32, false)
|
||||
);
|
||||
@ -1997,7 +2012,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
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))
|
||||
);
|
||||
@ -2044,7 +2059,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh, gen_operation(jh, shr,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), (gen_operation(jh, band,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false), (static_cast<uint32_t>(traits::XLEN)- 1))
|
||||
@ -2093,7 +2108,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_ext(jh, gen_operation(jh, sar,
|
||||
gen_ext(jh, gen_ext(jh,
|
||||
@ -2144,7 +2159,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
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))
|
||||
);
|
||||
@ -2191,7 +2206,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
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))
|
||||
);
|
||||
@ -2412,7 +2427,7 @@ private:
|
||||
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_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
xrd);
|
||||
}
|
||||
else{
|
||||
@ -2467,7 +2482,7 @@ private:
|
||||
, 4);
|
||||
}
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
xrd);
|
||||
}
|
||||
}
|
||||
@ -2519,7 +2534,7 @@ private:
|
||||
, 4);
|
||||
}
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
xrd);
|
||||
}
|
||||
}
|
||||
@ -2566,7 +2581,7 @@ private:
|
||||
auto xrd = gen_read_mem(jh, traits::CSR, csr, 4);
|
||||
gen_write_mem(jh, traits::CSR, csr, (uint32_t)zimm, 4);
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
xrd);
|
||||
}
|
||||
}
|
||||
@ -2617,7 +2632,7 @@ private:
|
||||
, 4);
|
||||
}
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
xrd);
|
||||
}
|
||||
}
|
||||
@ -2668,7 +2683,7 @@ private:
|
||||
, 4);
|
||||
}
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
xrd);
|
||||
}
|
||||
}
|
||||
@ -2758,7 +2773,7 @@ private:
|
||||
load_reg_from_mem(jh, traits::X0 + rs2), 32, true), 64, true), 128, true))
|
||||
), 64, true);
|
||||
if(rd!=0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
res, 32, true));
|
||||
}
|
||||
@ -2812,7 +2827,7 @@ private:
|
||||
load_reg_from_mem(jh, traits::X0 + rs2), 32, true), 64, true), 128, true))
|
||||
), 64, true);
|
||||
if(rd!=0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, sar,
|
||||
res, gen_ext(jh, static_cast<uint32_t>(traits::XLEN), 64, false))
|
||||
@ -2867,7 +2882,7 @@ private:
|
||||
load_reg_from_mem(jh, traits::X0 + rs2), 64, false), 128, false))
|
||||
), 64, true);
|
||||
if(rd!=0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, sar,
|
||||
res, gen_ext(jh, static_cast<uint32_t>(traits::XLEN), 64, false))
|
||||
@ -2921,7 +2936,7 @@ private:
|
||||
load_reg_from_mem(jh, traits::X0 + rs2), 64, false), 128, false))
|
||||
), 64, false);
|
||||
if(rd!=0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, shr,
|
||||
res, gen_ext(jh, static_cast<uint32_t>(traits::XLEN), 64, false))
|
||||
@ -2992,13 +3007,13 @@ private:
|
||||
auto label_else = cc.newLabel();
|
||||
cc.je(label_else);
|
||||
{
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
MMIN);
|
||||
}
|
||||
cc.jmp(label_merge);
|
||||
cc.bind(label_else);
|
||||
{
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, idiv,
|
||||
gen_ext(jh, dividend, 64, true), gen_ext(jh, divisor, 64, true))
|
||||
@ -3009,7 +3024,7 @@ private:
|
||||
cc.jmp(label_merge);
|
||||
cc.bind(label_else);
|
||||
{
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
(uint32_t)- 1);
|
||||
}
|
||||
cc.bind(label_merge);
|
||||
@ -3063,7 +3078,7 @@ private:
|
||||
cc.je(label_else);
|
||||
{
|
||||
if(rd!=0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, div,
|
||||
load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2))
|
||||
@ -3074,7 +3089,7 @@ private:
|
||||
cc.bind(label_else);
|
||||
{
|
||||
if(rd!=0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
(uint32_t)- 1);
|
||||
}
|
||||
}
|
||||
@ -3141,7 +3156,7 @@ private:
|
||||
cc.je(label_else);
|
||||
{
|
||||
if(rd!=0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh, 0, 32, false)
|
||||
);
|
||||
}
|
||||
@ -3150,7 +3165,7 @@ private:
|
||||
cc.bind(label_else);
|
||||
{
|
||||
if(rd!=0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, srem,
|
||||
gen_ext(jh,
|
||||
@ -3165,7 +3180,7 @@ private:
|
||||
cc.bind(label_else);
|
||||
{
|
||||
if(rd!=0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
load_reg_from_mem(jh, traits::X0 + rs1));
|
||||
}
|
||||
}
|
||||
@ -3219,7 +3234,7 @@ private:
|
||||
cc.je(label_else);
|
||||
{
|
||||
if(rd!=0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_operation(jh, urem,
|
||||
load_reg_from_mem(jh, traits::X0 + rs1), load_reg_from_mem(jh, traits::X0 + rs2))
|
||||
);
|
||||
@ -3229,7 +3244,7 @@ private:
|
||||
cc.bind(label_else);
|
||||
{
|
||||
if(rd!=0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
load_reg_from_mem(jh, traits::X0 + rs1));
|
||||
}
|
||||
}
|
||||
@ -3271,7 +3286,7 @@ private:
|
||||
cc.comment("\n//behavior:");
|
||||
/*generate behavior*/
|
||||
if(imm){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd+ 8),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd+ 8),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, add,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + 2), 64, false), gen_ext(jh, imm, 64, false))
|
||||
@ -3320,7 +3335,7 @@ private:
|
||||
(gen_operation(jh, add,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1+ 8), 64, false), gen_ext(jh, uimm, 64, false))
|
||||
), 32, false);
|
||||
cc.mov(get_reg_ptr(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));
|
||||
@ -3406,7 +3421,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rs1!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rs1),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rs1),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, add,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs1), 64, false), gen_ext(jh, (int8_t)sext<6>(imm), 64, true))
|
||||
@ -3480,11 +3495,11 @@ private:
|
||||
gen_instr_prologue(jh, pc.val);
|
||||
cc.comment("\n//behavior:");
|
||||
/*generate behavior*/
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ 1),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ 1),
|
||||
(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_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
auto returnValue = BRANCH;
|
||||
|
||||
gen_instr_epilogue(jh);
|
||||
@ -3525,7 +3540,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
(uint32_t)((int8_t)sext<6>(imm)));
|
||||
}
|
||||
}
|
||||
@ -3568,7 +3583,7 @@ private:
|
||||
gen_raise(jh, 0, 2);
|
||||
}
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
(uint32_t)((int32_t)sext<18>(imm)));
|
||||
}
|
||||
auto returnValue = CONT;
|
||||
@ -3606,7 +3621,7 @@ private:
|
||||
cc.comment("\n//behavior:");
|
||||
/*generate behavior*/
|
||||
if(nzimm){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ 2),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ 2),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, add,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + 2), 64, false), gen_ext(jh, (int16_t)sext<10>(nzimm), 64, true))
|
||||
@ -3684,7 +3699,7 @@ private:
|
||||
gen_instr_prologue(jh, pc.val);
|
||||
cc.comment("\n//behavior:");
|
||||
/*generate behavior*/
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rs1+ 8),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rs1+ 8),
|
||||
gen_operation(jh, shr,
|
||||
load_reg_from_mem(jh, traits::X0 + rs1+ 8), gen_ext(jh, shamt, 32, false))
|
||||
);
|
||||
@ -3724,7 +3739,7 @@ private:
|
||||
cc.comment("\n//behavior:");
|
||||
/*generate behavior*/
|
||||
if(shamt){
|
||||
cc.mov(get_reg_ptr(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,
|
||||
@ -3733,7 +3748,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(static_cast<uint32_t>(traits::XLEN)== 128){
|
||||
cc.mov(get_reg_ptr(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,
|
||||
@ -3776,7 +3791,7 @@ private:
|
||||
gen_instr_prologue(jh, pc.val);
|
||||
cc.comment("\n//behavior:");
|
||||
/*generate behavior*/
|
||||
cc.mov(get_reg_ptr(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), gen_ext(jh, (int8_t)sext<6>(imm), 32, true))
|
||||
@ -3816,7 +3831,7 @@ private:
|
||||
gen_instr_prologue(jh, pc.val);
|
||||
cc.comment("\n//behavior:");
|
||||
/*generate behavior*/
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd+ 8),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd+ 8),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, sub,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rd+ 8), 64, false), gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2+ 8), 64, false))
|
||||
@ -3856,7 +3871,7 @@ private:
|
||||
gen_instr_prologue(jh, pc.val);
|
||||
cc.comment("\n//behavior:");
|
||||
/*generate behavior*/
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd+ 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))
|
||||
);
|
||||
@ -3895,7 +3910,7 @@ private:
|
||||
gen_instr_prologue(jh, pc.val);
|
||||
cc.comment("\n//behavior:");
|
||||
/*generate behavior*/
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd+ 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))
|
||||
);
|
||||
@ -3934,7 +3949,7 @@ private:
|
||||
gen_instr_prologue(jh, pc.val);
|
||||
cc.comment("\n//behavior:");
|
||||
/*generate behavior*/
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd+ 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))
|
||||
);
|
||||
@ -3974,7 +3989,7 @@ private:
|
||||
/*generate behavior*/
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<12>(imm));
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
auto returnValue = BRANCH;
|
||||
|
||||
gen_instr_epilogue(jh);
|
||||
@ -4018,7 +4033,7 @@ private:
|
||||
{
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm));
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
cc.bind(label_merge);
|
||||
auto returnValue = BRANCH;
|
||||
@ -4064,7 +4079,7 @@ private:
|
||||
{
|
||||
auto PC_val_v = (uint32_t)(PC+(int16_t)sext<9>(imm));
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
cc.bind(label_merge);
|
||||
auto returnValue = BRANCH;
|
||||
@ -4107,7 +4122,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rs1!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rs1),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rs1),
|
||||
gen_operation(jh, shl,
|
||||
load_reg_from_mem(jh, traits::X0 + rs1), gen_ext(jh, nzuimm, 32, false))
|
||||
);
|
||||
@ -4156,7 +4171,7 @@ private:
|
||||
(gen_operation(jh, add,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + 2), 64, false), gen_ext(jh, uimm, 64, false))
|
||||
), 32, false);
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
gen_ext(jh,
|
||||
gen_read_mem(jh, traits::MEM, offs, 4), 32, false), 32, true));
|
||||
@ -4201,7 +4216,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
load_reg_from_mem(jh, traits::X0 + rs2));
|
||||
}
|
||||
}
|
||||
@ -4244,7 +4259,7 @@ private:
|
||||
load_reg_from_mem(jh, traits::X0 + rs1%static_cast<uint32_t>(traits::RFS)), gen_ext(jh, ~ 0x1, 32, false))
|
||||
;
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
else{
|
||||
gen_raise(jh, 0, 2);
|
||||
@ -4322,7 +4337,7 @@ private:
|
||||
}
|
||||
else{
|
||||
if(rd!= 0){
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ rd),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ rd),
|
||||
gen_ext(jh,
|
||||
(gen_operation(jh, add,
|
||||
gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rd), 64, false), gen_ext(jh, load_reg_from_mem(jh, traits::X0 + rs2), 64, false))
|
||||
@ -4368,13 +4383,13 @@ private:
|
||||
}
|
||||
else{
|
||||
auto new_pc = load_reg_from_mem(jh, traits::X0 + rs1);
|
||||
cc.mov(get_reg_ptr(jh, traits::X0+ 1),
|
||||
cc.mov(get_ptr_for(jh, traits::X0+ 1),
|
||||
(uint32_t)(PC+ 2));
|
||||
auto PC_val_v = gen_operation(jh, band,
|
||||
new_pc, gen_ext(jh, ~ 0x1, 32, false))
|
||||
;
|
||||
cc.mov(jh.next_pc, PC_val_v);
|
||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), 32U);
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), 32U);
|
||||
}
|
||||
auto returnValue = BRANCH;
|
||||
|
||||
@ -4556,11 +4571,6 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CODE_WORD> void debug_fn(CODE_WORD instr) {
|
||||
volatile CODE_WORD x = instr;
|
||||
instr = 2 * x;
|
||||
}
|
||||
|
||||
template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); }
|
||||
|
||||
template <typename ARCH>
|
||||
@ -4574,8 +4584,7 @@ vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
||||
}
|
||||
|
||||
template <typename ARCH>
|
||||
continuation_e
|
||||
vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, jit_holder& jh) {
|
||||
continuation_e vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, jit_holder& jh) {
|
||||
enum {TRAP_ID=1<<16};
|
||||
code_word_t instr = 0;
|
||||
phys_addr_t paddr(pc);
|
||||
@ -4593,6 +4602,96 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||
f = &this_class::illegal_intruction;
|
||||
return (this->*f)(pc, instr, jh);
|
||||
}
|
||||
template <typename ARCH>
|
||||
void vm_impl<ARCH>::gen_instr_prologue(jit_holder& jh, addr_t pc) {
|
||||
auto& cc = jh.cc;
|
||||
cc.mov(jh.pc, pc);
|
||||
|
||||
cc.comment("\n//(*icount)++;");
|
||||
cc.inc(get_ptr_for(jh, traits::ICOUNT));
|
||||
|
||||
cc.comment("\n//*pc=*next_pc;");
|
||||
cc.mov(get_ptr_for(jh, traits::PC), jh.next_pc);
|
||||
|
||||
cc.comment("\n//*trap_state=*pending_trap;");
|
||||
x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE);
|
||||
cc.mov(current_trap_state, get_ptr_for(jh, traits::TRAP_STATE));
|
||||
cc.mov(get_ptr_for(jh, traits::PENDING_TRAP), current_trap_state);
|
||||
|
||||
cc.comment("\n//increment *next_pc");
|
||||
cc.mov(jh.next_pc, pc);
|
||||
}
|
||||
template <typename ARCH>
|
||||
void vm_impl<ARCH>::gen_instr_epilogue(jit_holder& jh) {
|
||||
auto& cc = jh.cc;
|
||||
|
||||
cc.comment("\n//if(*trap_state!=0) goto trap_entry;");
|
||||
x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE);
|
||||
cc.mov(current_trap_state, get_ptr_for(jh, traits::TRAP_STATE));
|
||||
cc.cmp(current_trap_state, 0);
|
||||
cc.jne(jh.trap_entry);
|
||||
|
||||
// TODO: Does not need to be done for every instruction, only when needed (by plugin)
|
||||
cc.comment("\n//write back regs to mem");
|
||||
write_reg_to_mem(jh, jh.pc, traits::PC);
|
||||
write_reg_to_mem(jh, jh.next_pc, traits::NEXT_PC);
|
||||
}
|
||||
template <typename ARCH>
|
||||
void vm_impl<ARCH>::gen_block_prologue(jit_holder& jh){
|
||||
|
||||
jh.pc = load_reg_from_mem(jh, traits::PC);
|
||||
jh.next_pc = load_reg_from_mem(jh, traits::NEXT_PC);
|
||||
}
|
||||
template <typename ARCH>
|
||||
void vm_impl<ARCH>::gen_block_epilogue(jit_holder& jh){
|
||||
x86::Compiler& cc = jh.cc;
|
||||
cc.comment("\n//return *next_pc;");
|
||||
cc.ret(jh.next_pc);
|
||||
|
||||
cc.bind(jh.trap_entry);
|
||||
cc.comment("\n//Prepare for enter_trap;");
|
||||
// Make sure cached values are written back
|
||||
cc.comment("\n//write back regs to mem");
|
||||
write_reg_to_mem(jh, jh.pc, traits::PC);
|
||||
write_reg_to_mem(jh, jh.next_pc, traits::NEXT_PC);
|
||||
this->gen_sync(jh, POST_SYNC, -1);
|
||||
|
||||
x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE);
|
||||
cc.mov(current_trap_state, get_ptr_for(jh, traits::TRAP_STATE));
|
||||
|
||||
x86::Gp current_pc = get_reg_for(jh, traits::PC);
|
||||
cc.mov(current_pc, get_ptr_for(jh, traits::PC));
|
||||
|
||||
x86::Gp instr = cc.newInt32("instr");
|
||||
cc.mov(instr, 0); // this is not correct
|
||||
cc.comment("\n//enter trap call;");
|
||||
InvokeNode* call_enter_trap;
|
||||
cc.invoke(&call_enter_trap, &enter_trap, FuncSignatureT<uint64_t, void*, uint64_t, uint64_t, uint64_t>());
|
||||
call_enter_trap->setArg(0, jh.arch_if_ptr);
|
||||
call_enter_trap->setArg(1, current_trap_state);
|
||||
call_enter_trap->setArg(2, current_pc);
|
||||
call_enter_trap->setArg(3, instr);
|
||||
|
||||
x86::Gp current_next_pc = get_reg_for(jh, traits::NEXT_PC);
|
||||
cc.mov(current_next_pc, get_ptr_for(jh, traits::NEXT_PC));
|
||||
cc.mov(jh.next_pc, current_next_pc);
|
||||
|
||||
cc.comment("\n//*last_branch = std::numeric_limits<uint32_t>::max();");
|
||||
cc.mov(get_ptr_for(jh, traits::LAST_BRANCH), std::numeric_limits<uint32_t>::max());
|
||||
cc.comment("\n//return *next_pc;");
|
||||
cc.ret(jh.next_pc);
|
||||
}
|
||||
template <typename ARCH>
|
||||
inline void vm_impl<ARCH>:: gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause) {
|
||||
auto& cc = jh.cc;
|
||||
cc.comment("//gen_raise");
|
||||
auto tmp1 = get_reg_for(jh, traits::TRAP_STATE);
|
||||
cc.mov(tmp1, 0x80ULL << 24 | (cause << 16) | trap_id);
|
||||
cc.mov(get_ptr_for(jh, traits::TRAP_STATE), tmp1);
|
||||
auto tmp2 = get_reg_for(jh, traits::NEXT_PC);
|
||||
cc.mov(tmp2, std::numeric_limits<uint32_t>::max());
|
||||
cc.mov(get_ptr_for(jh, traits::NEXT_PC), tmp2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user