fix RVC description bugs, remove paged fetch

This commit is contained in:
Eyck Jentzsch 2021-03-13 10:19:30 +00:00
parent a5186ff88d
commit 80057eef32
3 changed files with 162 additions and 163 deletions

@ -1 +1 @@
Subproject commit d51b3e30f5c4b9863411fbecad6ec7e5793f865e
Subproject commit eab89af46bd1d6485e150111db1612ce8dca984b

View File

@ -165,8 +165,8 @@ protected:
inline void writeSpace2(typename super::mem_type_e space, uint64_t addr, uint16_t data){super::write_mem(space, addr, data);}
inline void writeSpace4(typename super::mem_type_e space, uint64_t addr, uint32_t data){super::write_mem(space, addr, data);}
inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){super::write_mem(space, addr, data);}
template<unsigned W, typename T>
inline T sext(T from) {
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);
@ -241,13 +241,13 @@ private:
static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK;
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
auto phys_pc = this->core.v2p(pc);
if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
if (this->core.read(phys_pc, 2, data) != iss::Ok) return iss::Err;
if ((data[0] & 0x3) == 0x3) // this is a 32bit instruction
if (this->core.read(this->core.v2p(pc + 2), 2, data + 2) != iss::Ok) return iss::Err;
} else {
//if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
// if (this->core.read(phys_pc, 2, data) != iss::Ok) return iss::Err;
// if ((data[0] & 0x3) == 0x3) // this is a 32bit instruction
// if (this->core.read(this->core.v2p(pc + 2), 2, data + 2) != iss::Ok) return iss::Err;
//} else {
if (this->core.read(phys_pc, 4, data) != iss::Ok) return iss::Err;
}
//}
return iss::Ok;
}
};

View File

@ -165,8 +165,8 @@ protected:
inline void writeSpace2(typename super::mem_type_e space, uint64_t addr, uint16_t data){super::write_mem(space, addr, data);}
inline void writeSpace4(typename super::mem_type_e space, uint64_t addr, uint32_t data){super::write_mem(space, addr, data);}
inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){super::write_mem(space, addr, data);}
template<unsigned W, typename T>
inline T sext(T from) {
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);
@ -449,8 +449,8 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
if(rd != 0) *(X+rd) = *PC + 4;
pc_assign(*NEXT_PC) = *PC + (int32_t)sext<21>(imm);
if(rd != 0) *(X+rd) = *PC + 4;
pc_assign(*NEXT_PC) = *PC + (int32_t)sext<21>(imm);
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2);
@ -485,9 +485,9 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
int32_t new_pc = *(X+rs1) + (int16_t)sext<12>(imm);
if(rd != 0) *(X+rd) = *PC + 4;
pc_assign(*NEXT_PC) = new_pc & ~ 0x1;
int32_t new_pc = *(X+rs1) + (int16_t)sext<12>(imm);
if(rd != 0) *(X+rd) = *PC + 2;
pc_assign(*NEXT_PC) = new_pc & ~ 0x1;
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 3);
@ -720,8 +720,8 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
int8_t res = (int8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm));
if(rd != 0) *(X+rd) = res;
int8_t res = (int8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm));
if(rd != 0) *(X+rd) = res;
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 10);
@ -756,12 +756,12 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0, 4);
else {
int16_t res = (int16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm));
if(rd != 0) *(X+rd) = res;
}
uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0, 4);
else {
int16_t res = (int16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm));
if(rd != 0) *(X+rd) = res;
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 11);
@ -796,12 +796,12 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0, 4);
else {
int32_t res = (int32_t)readSpace4(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm));
if(rd != 0) *(X+rd) = (uint32_t)res;
}
uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0, 4);
else {
int32_t res = (int32_t)readSpace4(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm));
if(rd != 0) *(X+rd) = (uint32_t)res;
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 12);
@ -836,8 +836,8 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
uint8_t res = (uint8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm));
if(rd != 0) *(X+rd) = res;
uint8_t res = (uint8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm));
if(rd != 0) *(X+rd) = res;
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 13);
@ -872,12 +872,12 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0, 4);
else {
uint16_t res = (uint16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm));
if(rd != 0) *(X+rd) = res;
}
uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
if(traits::eei_aligned_addresses && (load_address & 0x1)) raise(0, 4);
else {
uint16_t res = (uint16_t)readSpace2(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm));
if(rd != 0) *(X+rd) = res;
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 14);
@ -945,9 +945,9 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm);
if(traits::eei_aligned_addresses && (store_address & 0x1)) raise(0, 6);
else writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2));
uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm);
if(traits::eei_aligned_addresses && (store_address & 0x1)) raise(0, 6);
else writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2));
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 16);
@ -982,9 +982,9 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm);
if(traits::eei_aligned_addresses && (store_address & 0x3)) raise(0, 6);
else writeSpace4(traits::MEM, store_address, *(X+rs2));
uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm);
if(traits::eei_aligned_addresses && (store_address & 0x3)) raise(0, 6);
else writeSpace4(traits::MEM, store_address, *(X+rs2));
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 17);
@ -1217,10 +1217,10 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
if(shamt > 31) {
raise(0, 0);
raise(0, 0);
}
else {
if(rd != 0) *(X+rd) = *(X+rs1) << shamt;
if(rd != 0) *(X+rd) = *(X+rs1) << shamt;
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 24);
@ -1255,10 +1255,10 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
if(shamt > 31) {
raise(0, 0);
raise(0, 0);
}
else {
if(rd != 0) *(X+rd) = *(X+rs1) >> shamt;
if(rd != 0) *(X+rd) = *(X+rs1) >> shamt;
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 25);
@ -1293,10 +1293,10 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
if(shamt > 31) {
raise(0, 0);
raise(0, 0);
}
else {
if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> shamt;
if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> shamt;
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 26);
@ -1889,8 +1889,8 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
writeSpace1(traits::FENCE, traits::fencevmal, (uint8_t)rs1);
writeSpace1(traits::FENCE, traits::fencevmau, (uint8_t)rs2);
writeSpace4(traits::FENCE, traits::fencevmal, (uint32_t)rs1);
writeSpace4(traits::FENCE, traits::fencevmau, (uint32_t)rs2);
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45);
@ -1925,15 +1925,15 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
uint32_t rs_val = *(X+rs1);
if(rd != 0) {
uint32_t csr_val = readSpace4(traits::CSR, csr);
writeSpace4(traits::CSR, csr, rs_val);
*(X+rd) = csr_val;
}
else {
writeSpace4(traits::CSR, csr, rs_val);
}
uint32_t rs_val = *(X+rs1);
if(rd != 0) {
uint32_t csr_val = readSpace4(traits::CSR, csr);
writeSpace4(traits::CSR, csr, rs_val);
*(X+rd) = csr_val;
}
else {
writeSpace4(traits::CSR, csr, rs_val);
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 46);
@ -1968,10 +1968,10 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
uint32_t xrd = readSpace4(traits::CSR, csr);
uint32_t xrs1 = *(X+rs1);
if(rd != 0) *(X+rd) = xrd;
if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1);
uint32_t xrd = readSpace4(traits::CSR, csr);
uint32_t xrs1 = *(X+rs1);
if(rd != 0) *(X+rd) = xrd;
if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1);
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 47);
@ -2006,10 +2006,10 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
uint32_t xrd = readSpace4(traits::CSR, csr);
uint32_t xrs1 = *(X+rs1);
if(rd != 0) *(X+rd) = xrd;
if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1);
uint32_t xrd = readSpace4(traits::CSR, csr);
uint32_t xrs1 = *(X+rs1);
if(rd != 0) *(X+rd) = xrd;
if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1);
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 48);
@ -2044,8 +2044,8 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
if(rd != 0) *(X+rd) = readSpace4(traits::CSR, csr);
writeSpace4(traits::CSR, csr, (uint32_t)zimm);
if(rd != 0) *(X+rd) = readSpace4(traits::CSR, csr);
writeSpace4(traits::CSR, csr, (uint32_t)zimm);
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 49);
@ -2080,9 +2080,9 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
uint32_t res = readSpace4(traits::CSR, csr);
if(zimm != 0) writeSpace4(traits::CSR, csr, res | (uint32_t)zimm);
if(rd != 0) *(X+rd) = res;
uint32_t res = readSpace4(traits::CSR, csr);
if(zimm != 0) writeSpace4(traits::CSR, csr, res | (uint32_t)zimm);
if(rd != 0) *(X+rd) = res;
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50);
@ -2117,9 +2117,9 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
uint32_t res = readSpace4(traits::CSR, csr);
if(rd != 0) *(X+rd) = res;
if(zimm != 0) writeSpace4(traits::CSR, csr, res & ~ ((uint32_t)zimm));
uint32_t res = readSpace4(traits::CSR, csr);
if(rd != 0) *(X+rd) = res;
if(zimm != 0) writeSpace4(traits::CSR, csr, res & ~ ((uint32_t)zimm));
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51);
@ -2154,10 +2154,10 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
if(rd != 0) {
int64_t res = (int64_t)*(X+rs1) * (int64_t)*(X+rs2);
*(X+rd) = (uint32_t)res;
}
if(rd != 0) {
int64_t res = (int32_t)*(X+rs1) * (int32_t)*(X+rs2);
*(X+rd) = (uint32_t)res;
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 52);
@ -2192,10 +2192,10 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
if(rd != 0) {
int64_t res = (int64_t)*(X+rs1) * (int64_t)*(X+rs2);
*(X+rd) = (uint32_t)(res >> traits::XLEN);
}
if(rd != 0) {
int64_t res = (int32_t)*(X+rs1) * (int32_t)*(X+rs2);
*(X+rd) = (uint32_t)(res >> traits::XLEN);
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 53);
@ -2230,10 +2230,10 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
if(rd != 0) {
int64_t res = (int64_t)*(X+rs1) * (uint64_t)*(X+rs2);
*(X+rd) = (uint32_t)res;
}
if(rd != 0) {
int64_t res = (int32_t)*(X+rs1) * (uint32_t)*(X+rs2);
*(X+rd) = (uint32_t)res;
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 54);
@ -2268,10 +2268,10 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
if(rd != 0) {
uint64_t res = (uint64_t)*(X+rs1) * (uint64_t)*(X+rs2);
*(X+rd) = (uint32_t)res;
}
if(rd != 0) {
uint64_t res = (uint32_t)*(X+rs1) * (uint32_t)*(X+rs2);
*(X+rd) = (uint32_t)res;
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 55);
@ -2306,14 +2306,14 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
if(rd != 0) {
if(*(X+rs2) != 0) {
uint32_t MMIN = 1 << (traits::XLEN - 1);
if(*(X+rs1) == MMIN && (int8_t)*(X+rs2) == - 1) *(X+rd) = MMIN;
else *(X+rd) = (int8_t)*(X+rs1) / (int8_t)*(X+rs2);
}
else *(X+rd) = - 1;
}
if(rd != 0) {
if(*(X+rs2) != 0) {
uint32_t MMIN = 1 << (traits::XLEN - 1);
if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = MMIN;
else *(X+rd) = (int32_t)*(X+rs1) / (int32_t)*(X+rs2);
}
else *(X+rd) = - 1;
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 56);
@ -2348,10 +2348,10 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
if(rd != 0) {
if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) / *(X+rs2);
else *(X+rd) = - 1;
}
if(rd != 0) {
if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) / *(X+rs2);
else *(X+rd) = - 1;
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 57);
@ -2386,14 +2386,14 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
if(rd != 0) {
if(*(X+rs2) != 0) {
uint32_t MMIN = 1 << (traits::XLEN - 1);
if(*(X+rs1) == MMIN && *(X+rs2) == - 1) *(X+rd) = 0;
else *(X+rd) = (int8_t)*(X+rs1) % (int8_t)*(X+rs2);
}
else *(X+rd) = *(X+rs1);
}
if(rd != 0) {
if(*(X+rs2) != 0) {
uint32_t MMIN = 1 << (traits::XLEN - 1);
if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = 0;
else *(X+rd) = (int32_t)*(X+rs1) % (int32_t)*(X+rs2);
}
else *(X+rd) = *(X+rs1);
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 58);
@ -2428,10 +2428,10 @@ private:
*NEXT_PC = *PC + 4;
// execute instruction
{
if(rd != 0) {
if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) % *(X+rs2);
else *(X+rd) = *(X+rs1);
}
if(rd != 0) {
if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) % *(X+rs2);
else *(X+rd) = *(X+rs1);
}
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 59);
@ -2465,8 +2465,8 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
if(imm == 0) raise(0, 2);
*(X+(rd + 8)) = *(X+2) + imm;
if(imm == 0) raise(0, 2);
*(X+(rd + 8)) = *(X+2) + imm;
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 60);
@ -2501,9 +2501,9 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
uint32_t load_address = *(X+(rs1 + 8)) + uimm;
if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0, 4);
else *(X+(rd + 8)) = (int32_t)readSpace4(traits::MEM, load_address);
uint32_t load_address = *(X+(rs1 + 8)) + uimm;
if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0, 4);
else *(X+(rd + 8)) = (int32_t)readSpace4(traits::MEM, load_address);
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 61);
@ -2538,9 +2538,9 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
uint32_t load_address = *(X+(rs1 + 8)) + uimm;
if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0, 6);
else writeSpace4(traits::MEM, load_address, *(X+(rs2 + 8)));
uint32_t load_address = *(X+(rs1 + 8)) + uimm;
if(traits::eei_aligned_addresses && (load_address & 0x3)) raise(0, 6);
else writeSpace4(traits::MEM, load_address, *(X+(rs2 + 8)));
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 62);
@ -2634,8 +2634,8 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
*(X+1) = *PC + 2;
pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm);
*(X+1) = *PC + 2;
pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm);
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65);
@ -2669,7 +2669,7 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
if(rd == 0) *(X+rd) = (int8_t)sext<6>(imm);
if(rd != 0) *(X+rd) = (uint32_t)(int32_t)sext<6>(imm);
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66);
@ -2703,9 +2703,9 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
if(rd == 0) raise(0, 2);
if(imm == 0) raise(0, 2);
*(X+rd) = (int32_t)sext<18>(imm);
if(rd == 0) raise(0, 2);
if(imm == 0) raise(0, 2);
*(X+rd) = (int32_t)sext<18>(imm);
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67);
@ -2722,13 +2722,12 @@ private:
compile_ret_t __caddi16sp(virt_addr_t& pc, code_word_t instr){
// pre execution stuff
this->do_sync(PRE_SYNC, 68);
uint16_t nzimm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4));
uint16_t imm = ((bit_sub<12,1>(instr) << 9));
uint16_t nzimm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "caddi16sp"),
fmt::arg("imm", nzimm));
"{mnemonic:10} {nzimm:#05x}", fmt::arg("mnemonic", "caddi16sp"),
fmt::arg("nzimm", nzimm));
this->core.disass_output(pc.val, mnemonic);
}
@ -2772,8 +2771,8 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
uint8_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = *(X+rs1_idx) << shamt;
uint32_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = *(X+rs1_idx) >> shamt;
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69);
@ -2807,12 +2806,12 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
if(shamt) {
uint8_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt;
uint32_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt;
}
else if(traits::XLEN == 128) {
uint8_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64;
uint32_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64;
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 70);
@ -2846,8 +2845,8 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
uint8_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm);
uint32_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm);
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71);
@ -2881,8 +2880,8 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
uint8_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) - *(X+(rs2 + 8));
uint32_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) - *(X+(rs2 + 8));
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 72);
@ -2916,8 +2915,8 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
uint8_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) ^ *(X+(rs2 + 8));
uint32_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) ^ *(X+(rs2 + 8));
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 73);
@ -2951,8 +2950,8 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
uint8_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) | *(X+(rs2 + 8));
uint32_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) | *(X+(rs2 + 8));
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 74);
@ -2986,8 +2985,8 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
uint8_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) & *(X+(rs2 + 8));
uint32_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) & *(X+(rs2 + 8));
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 75);
@ -3148,8 +3147,8 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
if(rd) {
uint32_t offs = *(X+2) + uimm;
*(X+rd) = (int32_t)readSpace4(traits::MEM, offs);
uint32_t offs = *(X+2) + uimm;
*(X+rd) = (int32_t)readSpace4(traits::MEM, offs);
}
else raise(0, 2);
// post execution stuff
@ -3279,8 +3278,8 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
*(X+1) = *PC + 2;
pc_assign(*NEXT_PC) = *(X+rs1);
*(X+1) = *PC + 2;
pc_assign(*NEXT_PC) = *(X+rs1);
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 84);
@ -3341,8 +3340,8 @@ private:
*NEXT_PC = *PC + 2;
// execute instruction
{
uint32_t offs = *(X+2) + uimm;
writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2));
uint32_t offs = *(X+2) + uimm;
writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2));
}
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 86);
@ -3405,13 +3404,13 @@ private:
static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK;
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
auto phys_pc = this->core.v2p(pc);
if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
if (this->core.read(phys_pc, 2, data) != iss::Ok) return iss::Err;
if ((data[0] & 0x3) == 0x3) // this is a 32bit instruction
if (this->core.read(this->core.v2p(pc + 2), 2, data + 2) != iss::Ok) return iss::Err;
} else {
//if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
// if (this->core.read(phys_pc, 2, data) != iss::Ok) return iss::Err;
// if ((data[0] & 0x3) == 0x3) // this is a 32bit instruction
// if (this->core.read(this->core.v2p(pc + 2), 2, data + 2) != iss::Ok) return iss::Err;
//} else {
if (this->core.read(phys_pc, 4, data) != iss::Ok) return iss::Err;
}
//}
return iss::Ok;
}
};