checking: working

This commit is contained in:
Eyck-Alexander Jentzsch 2024-04-26 17:06:26 +02:00
parent b25b7848c6
commit 602bc6e06a
1 changed files with 191 additions and 92 deletions

View File

@ -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);
}