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 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 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);}
|
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>
|
template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
|
||||||
inline T sext(T from) {
|
inline S sext(U from) {
|
||||||
auto mask = (1ULL<<W) - 1;
|
auto mask = (1ULL<<W) - 1;
|
||||||
auto sign_mask = 1ULL<<(W-1);
|
auto sign_mask = 1ULL<<(W-1);
|
||||||
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
||||||
|
@ -241,13 +241,13 @@ private:
|
||||||
static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK;
|
static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK;
|
||||||
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
|
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
|
||||||
auto phys_pc = this->core.v2p(pc);
|
auto phys_pc = this->core.v2p(pc);
|
||||||
if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
|
//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 (this->core.read(phys_pc, 2, data) != iss::Ok) return iss::Err;
|
||||||
if ((data[0] & 0x3) == 0x3) // this is a 32bit instruction
|
// 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;
|
// if (this->core.read(this->core.v2p(pc + 2), 2, data + 2) != iss::Ok) return iss::Err;
|
||||||
} else {
|
//} else {
|
||||||
if (this->core.read(phys_pc, 4, data) != iss::Ok) return iss::Err;
|
if (this->core.read(phys_pc, 4, data) != iss::Ok) return iss::Err;
|
||||||
}
|
//}
|
||||||
return iss::Ok;
|
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 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 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);}
|
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>
|
template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
|
||||||
inline T sext(T from) {
|
inline S sext(U from) {
|
||||||
auto mask = (1ULL<<W) - 1;
|
auto mask = (1ULL<<W) - 1;
|
||||||
auto sign_mask = 1ULL<<(W-1);
|
auto sign_mask = 1ULL<<(W-1);
|
||||||
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
||||||
|
@ -486,7 +486,7 @@ private:
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
int32_t new_pc = *(X+rs1) + (int16_t)sext<12>(imm);
|
int32_t new_pc = *(X+rs1) + (int16_t)sext<12>(imm);
|
||||||
if(rd != 0) *(X+rd) = *PC + 4;
|
if(rd != 0) *(X+rd) = *PC + 2;
|
||||||
pc_assign(*NEXT_PC) = new_pc & ~ 0x1;
|
pc_assign(*NEXT_PC) = new_pc & ~ 0x1;
|
||||||
}
|
}
|
||||||
// post execution stuff
|
// post execution stuff
|
||||||
|
@ -1889,8 +1889,8 @@ private:
|
||||||
*NEXT_PC = *PC + 4;
|
*NEXT_PC = *PC + 4;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
writeSpace1(traits::FENCE, traits::fencevmal, (uint8_t)rs1);
|
writeSpace4(traits::FENCE, traits::fencevmal, (uint32_t)rs1);
|
||||||
writeSpace1(traits::FENCE, traits::fencevmau, (uint8_t)rs2);
|
writeSpace4(traits::FENCE, traits::fencevmau, (uint32_t)rs2);
|
||||||
}
|
}
|
||||||
// post execution stuff
|
// post execution stuff
|
||||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45);
|
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45);
|
||||||
|
@ -2155,7 +2155,7 @@ private:
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
if(rd != 0) {
|
if(rd != 0) {
|
||||||
int64_t res = (int64_t)*(X+rs1) * (int64_t)*(X+rs2);
|
int64_t res = (int32_t)*(X+rs1) * (int32_t)*(X+rs2);
|
||||||
*(X+rd) = (uint32_t)res;
|
*(X+rd) = (uint32_t)res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2193,7 +2193,7 @@ private:
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
if(rd != 0) {
|
if(rd != 0) {
|
||||||
int64_t res = (int64_t)*(X+rs1) * (int64_t)*(X+rs2);
|
int64_t res = (int32_t)*(X+rs1) * (int32_t)*(X+rs2);
|
||||||
*(X+rd) = (uint32_t)(res >> traits::XLEN);
|
*(X+rd) = (uint32_t)(res >> traits::XLEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2231,7 +2231,7 @@ private:
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
if(rd != 0) {
|
if(rd != 0) {
|
||||||
int64_t res = (int64_t)*(X+rs1) * (uint64_t)*(X+rs2);
|
int64_t res = (int32_t)*(X+rs1) * (uint32_t)*(X+rs2);
|
||||||
*(X+rd) = (uint32_t)res;
|
*(X+rd) = (uint32_t)res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2269,7 +2269,7 @@ private:
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
if(rd != 0) {
|
if(rd != 0) {
|
||||||
uint64_t res = (uint64_t)*(X+rs1) * (uint64_t)*(X+rs2);
|
uint64_t res = (uint32_t)*(X+rs1) * (uint32_t)*(X+rs2);
|
||||||
*(X+rd) = (uint32_t)res;
|
*(X+rd) = (uint32_t)res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2309,8 +2309,8 @@ private:
|
||||||
if(rd != 0) {
|
if(rd != 0) {
|
||||||
if(*(X+rs2) != 0) {
|
if(*(X+rs2) != 0) {
|
||||||
uint32_t MMIN = 1 << (traits::XLEN - 1);
|
uint32_t MMIN = 1 << (traits::XLEN - 1);
|
||||||
if(*(X+rs1) == MMIN && (int8_t)*(X+rs2) == - 1) *(X+rd) = MMIN;
|
if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = MMIN;
|
||||||
else *(X+rd) = (int8_t)*(X+rs1) / (int8_t)*(X+rs2);
|
else *(X+rd) = (int32_t)*(X+rs1) / (int32_t)*(X+rs2);
|
||||||
}
|
}
|
||||||
else *(X+rd) = - 1;
|
else *(X+rd) = - 1;
|
||||||
}
|
}
|
||||||
|
@ -2389,8 +2389,8 @@ private:
|
||||||
if(rd != 0) {
|
if(rd != 0) {
|
||||||
if(*(X+rs2) != 0) {
|
if(*(X+rs2) != 0) {
|
||||||
uint32_t MMIN = 1 << (traits::XLEN - 1);
|
uint32_t MMIN = 1 << (traits::XLEN - 1);
|
||||||
if(*(X+rs1) == MMIN && *(X+rs2) == - 1) *(X+rd) = 0;
|
if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = 0;
|
||||||
else *(X+rd) = (int8_t)*(X+rs1) % (int8_t)*(X+rs2);
|
else *(X+rd) = (int32_t)*(X+rs1) % (int32_t)*(X+rs2);
|
||||||
}
|
}
|
||||||
else *(X+rd) = *(X+rs1);
|
else *(X+rd) = *(X+rs1);
|
||||||
}
|
}
|
||||||
|
@ -2669,7 +2669,7 @@ private:
|
||||||
*NEXT_PC = *PC + 2;
|
*NEXT_PC = *PC + 2;
|
||||||
// execute instruction
|
// 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
|
// post execution stuff
|
||||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66);
|
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66);
|
||||||
|
@ -2722,13 +2722,12 @@ private:
|
||||||
compile_ret_t __caddi16sp(virt_addr_t& pc, code_word_t instr){
|
compile_ret_t __caddi16sp(virt_addr_t& pc, code_word_t instr){
|
||||||
// pre execution stuff
|
// pre execution stuff
|
||||||
this->do_sync(PRE_SYNC, 68);
|
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 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));
|
||||||
uint16_t imm = ((bit_sub<12,1>(instr) << 9));
|
|
||||||
if(this->disass_enabled){
|
if(this->disass_enabled){
|
||||||
/* generate console output when executing the command */
|
/* generate console output when executing the command */
|
||||||
auto mnemonic = fmt::format(
|
auto mnemonic = fmt::format(
|
||||||
"{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "caddi16sp"),
|
"{mnemonic:10} {nzimm:#05x}", fmt::arg("mnemonic", "caddi16sp"),
|
||||||
fmt::arg("imm", nzimm));
|
fmt::arg("nzimm", nzimm));
|
||||||
this->core.disass_output(pc.val, mnemonic);
|
this->core.disass_output(pc.val, mnemonic);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2772,8 +2771,8 @@ private:
|
||||||
*NEXT_PC = *PC + 2;
|
*NEXT_PC = *PC + 2;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
uint8_t rs1_idx = rs1 + 8;
|
uint32_t rs1_idx = rs1 + 8;
|
||||||
*(X+rs1_idx) = *(X+rs1_idx) << shamt;
|
*(X+rs1_idx) = *(X+rs1_idx) >> shamt;
|
||||||
}
|
}
|
||||||
// post execution stuff
|
// post execution stuff
|
||||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69);
|
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69);
|
||||||
|
@ -2807,11 +2806,11 @@ private:
|
||||||
*NEXT_PC = *PC + 2;
|
*NEXT_PC = *PC + 2;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
if(shamt) {
|
if(shamt) {
|
||||||
uint8_t rs1_idx = rs1 + 8;
|
uint32_t rs1_idx = rs1 + 8;
|
||||||
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt;
|
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt;
|
||||||
}
|
}
|
||||||
else if(traits::XLEN == 128) {
|
else if(traits::XLEN == 128) {
|
||||||
uint8_t rs1_idx = rs1 + 8;
|
uint32_t rs1_idx = rs1 + 8;
|
||||||
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64;
|
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64;
|
||||||
}
|
}
|
||||||
// post execution stuff
|
// post execution stuff
|
||||||
|
@ -2846,7 +2845,7 @@ private:
|
||||||
*NEXT_PC = *PC + 2;
|
*NEXT_PC = *PC + 2;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
uint8_t rs1_idx = rs1 + 8;
|
uint32_t rs1_idx = rs1 + 8;
|
||||||
*(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm);
|
*(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm);
|
||||||
}
|
}
|
||||||
// post execution stuff
|
// post execution stuff
|
||||||
|
@ -2881,7 +2880,7 @@ private:
|
||||||
*NEXT_PC = *PC + 2;
|
*NEXT_PC = *PC + 2;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
uint8_t rd_idx = rd + 8;
|
uint32_t rd_idx = rd + 8;
|
||||||
*(X+rd_idx) = *(X+rd_idx) - *(X+(rs2 + 8));
|
*(X+rd_idx) = *(X+rd_idx) - *(X+(rs2 + 8));
|
||||||
}
|
}
|
||||||
// post execution stuff
|
// post execution stuff
|
||||||
|
@ -2916,7 +2915,7 @@ private:
|
||||||
*NEXT_PC = *PC + 2;
|
*NEXT_PC = *PC + 2;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
uint8_t rd_idx = rd + 8;
|
uint32_t rd_idx = rd + 8;
|
||||||
*(X+rd_idx) = *(X+rd_idx) ^ *(X+(rs2 + 8));
|
*(X+rd_idx) = *(X+rd_idx) ^ *(X+(rs2 + 8));
|
||||||
}
|
}
|
||||||
// post execution stuff
|
// post execution stuff
|
||||||
|
@ -2951,7 +2950,7 @@ private:
|
||||||
*NEXT_PC = *PC + 2;
|
*NEXT_PC = *PC + 2;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
uint8_t rd_idx = rd + 8;
|
uint32_t rd_idx = rd + 8;
|
||||||
*(X+rd_idx) = *(X+rd_idx) | *(X+(rs2 + 8));
|
*(X+rd_idx) = *(X+rd_idx) | *(X+(rs2 + 8));
|
||||||
}
|
}
|
||||||
// post execution stuff
|
// post execution stuff
|
||||||
|
@ -2986,7 +2985,7 @@ private:
|
||||||
*NEXT_PC = *PC + 2;
|
*NEXT_PC = *PC + 2;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
uint8_t rd_idx = rd + 8;
|
uint32_t rd_idx = rd + 8;
|
||||||
*(X+rd_idx) = *(X+rd_idx) & *(X+(rs2 + 8));
|
*(X+rd_idx) = *(X+rd_idx) & *(X+(rs2 + 8));
|
||||||
}
|
}
|
||||||
// post execution stuff
|
// post execution stuff
|
||||||
|
@ -3405,13 +3404,13 @@ private:
|
||||||
static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK;
|
static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK;
|
||||||
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
|
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
|
||||||
auto phys_pc = this->core.v2p(pc);
|
auto phys_pc = this->core.v2p(pc);
|
||||||
if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
|
//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 (this->core.read(phys_pc, 2, data) != iss::Ok) return iss::Err;
|
||||||
if ((data[0] & 0x3) == 0x3) // this is a 32bit instruction
|
// 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;
|
// if (this->core.read(this->core.v2p(pc + 2), 2, data + 2) != iss::Ok) return iss::Err;
|
||||||
} else {
|
//} else {
|
||||||
if (this->core.read(phys_pc, 4, data) != iss::Ok) return iss::Err;
|
if (this->core.read(phys_pc, 4, data) != iss::Ok) return iss::Err;
|
||||||
}
|
//}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue