fix RVC description bugs, remove paged fetch
This commit is contained in:
parent
a5186ff88d
commit
80057eef32
@ -1 +1 @@
|
||||
Subproject commit d51b3e30f5c4b9863411fbecad6ec7e5793f865e
|
||||
Subproject commit eab89af46bd1d6485e150111db1612ce8dca984b
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user