Compare commits

...

4 Commits

5 changed files with 53 additions and 32 deletions

View File

@ -319,7 +319,8 @@ struct riscv_hart_common {
uint64_t tohost = tohost_dflt;
uint64_t fromhost = fromhost_dflt;
bool read_elf_file(std::string name, uint8_t expected_elf_class, std::function<iss::status(uint64_t, uint64_t, const uint8_t* const)> cb) {
bool read_elf_file(std::string name, uint8_t expected_elf_class,
std::function<iss::status(uint64_t, uint64_t, const uint8_t* const)> cb) {
// Create elfio reader
ELFIO::elfio reader;
// Load ELF data
@ -327,12 +328,12 @@ struct riscv_hart_common {
// check elf properties
if(reader.get_class() != expected_elf_class)
return false;
if(reader.get_type() != ET_EXEC)
return false;
if(reader.get_machine() != EM_RISCV)
if(reader.get_type() != ELFIO::ET_EXEC)
return false;
if(reader.get_machine() != ELFIO::EM_RISCV)
return false;
entry_address = reader.get_entry();
for(const auto pseg : reader.segments) {
for(const auto& pseg : reader.segments) {
const auto fsize = pseg->get_file_size(); // 0x42c/0x0
const auto seg_data = pseg->get_data();
const auto type = pseg->get_type();
@ -343,7 +344,7 @@ struct riscv_hart_common {
}
}
const auto sym_sec = reader.sections[".symtab"];
if(SHT_SYMTAB == sym_sec->get_type() || SHT_DYNSYM == sym_sec->get_type()) {
if(ELFIO::SHT_SYMTAB == sym_sec->get_type() || ELFIO::SHT_DYNSYM == sym_sec->get_type()) {
ELFIO::symbol_section_accessor symbols(reader, sym_sec);
auto sym_no = symbols.get_symbols_num();
std::string name;

View File

@ -572,7 +572,7 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg)
template <typename BASE, features_e FEAT, typename LOGCAT>
std::pair<uint64_t, bool> riscv_hart_m_p<BASE, FEAT, LOGCAT>::load_file(std::string name, int type) {
if(read_elf_file(name, sizeof(reg_t) == 4 ? ELFCLASS32 : ELFCLASS64,
if(read_elf_file(name, sizeof(reg_t) == 4 ? ELFIO::ELFCLASS32 : ELFIO::ELFCLASS64,
[this](uint64_t addr, uint64_t size, const uint8_t* const data) -> iss::status {
return this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE, traits<BASE>::MEM, addr, size,
data);
@ -706,7 +706,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write(const address_type type, c
<< std::hex << addr;
break;
default:
CPPLOG(TRACE) << prefix << "write of " << length << " bytes @addr " << addr;
CPPLOG(TRACE) << prefix << "write of " << length << " bytes @addr 0x" << std::hex << addr;
}
#endif
try {
@ -1326,7 +1326,8 @@ uint64_t riscv_hart_m_p<BASE, FEAT, LOGCAT>::enter_trap(uint64_t flags, uint64_t
#endif
if((flags & 0xffffffff) != 0xffffffff)
NSCLOG(INFO, LOGCAT) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause]) << "' ("
<< cause << ")" << " at address " << buffer.data() << " occurred";
<< cause << ")"
<< " at address " << buffer.data() << " occurred";
return this->reg.NEXT_PC;
}

View File

@ -555,7 +555,7 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
}
template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load_file(std::string name, int type) {
if(read_elf_file(name, sizeof(reg_t) == 4 ? ELFCLASS32 : ELFCLASS64,
if(read_elf_file(name, sizeof(reg_t) == 4 ? ELFIO::ELFCLASS32 : ELFIO::ELFCLASS64,
[this](uint64_t addr, uint64_t size, const uint8_t* const data) -> iss::status {
return this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE, traits<BASE>::MEM, addr, size,
data);
@ -1337,8 +1337,9 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
sprintf(buffer.data(), "0x%016lx", addr);
if((flags & 0xffffffff) != 0xffffffff)
CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause]) << "' ("
<< cause << ")" << " at address " << buffer.data() << " occurred, changing privilege level from "
<< lvl[cur_priv] << " to " << lvl[new_priv];
<< cause << ")"
<< " at address " << buffer.data() << " occurred, changing privilege level from " << lvl[cur_priv] << " to "
<< lvl[new_priv];
// reset trap state
this->reg.PRIV = new_priv;
this->reg.trap_state = 0;

View File

@ -649,7 +649,7 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg)
template <typename BASE, features_e FEAT, typename LOGCAT>
std::pair<uint64_t, bool> riscv_hart_mu_p<BASE, FEAT, LOGCAT>::load_file(std::string name, int type) {
if(read_elf_file(name, sizeof(reg_t) == 4 ? ELFCLASS32 : ELFCLASS64,
if(read_elf_file(name, sizeof(reg_t) == 4 ? ELFIO::ELFCLASS32 : ELFIO::ELFCLASS64,
[this](uint64_t addr, uint64_t size, const uint8_t* const data) -> iss::status {
return this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE, traits<BASE>::MEM, addr, size,
data);
@ -1565,8 +1565,9 @@ uint64_t riscv_hart_mu_p<BASE, FEAT, LOGCAT>::enter_trap(uint64_t flags, uint64_
#endif
if((flags & 0xffffffff) != 0xffffffff)
CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause]) << "' ("
<< cause << ")" << " at address " << buffer.data() << " occurred, changing privilege level from "
<< lvl[this->reg.PRIV] << " to " << lvl[new_priv];
<< cause << ")"
<< " at address " << buffer.data() << " occurred, changing privilege level from " << lvl[this->reg.PRIV]
<< " to " << lvl[new_priv];
// reset trap state
this->reg.PRIV = new_priv;
this->reg.trap_state = 0;

View File

@ -203,8 +203,8 @@ uint32_t fclass_s(uint32_t v1) {
uA.f = a;
uiA = uA.ui;
uint_fast16_t infOrNaN = expF32UI(uiA) == 0xFF;
uint_fast16_t subnormalOrZero = expF32UI(uiA) == 0;
bool infOrNaN = expF32UI(uiA) == 0xFF;
bool subnormalOrZero = expF32UI(uiA) == 0;
bool sign = signF32UI(uiA);
bool fracZero = fracF32UI(uiA) == 0;
bool isNaN = isNaNF32UI(uiA);
@ -217,9 +217,13 @@ uint32_t fclass_s(uint32_t v1) {
}
uint32_t fconv_d2f(uint64_t v1, uint8_t mode) {
bool isNan = isNaNF64UI(v1);
bool isSNaN = softfloat_isSigNaNF64UI(v1);
softfloat_roundingMode = rmm_map.at(mode);
bool nan = (v1 & defaultNaNF64UI) == defaultNaNF64UI;
if(nan) {
softfloat_exceptionFlags = 0;
if(isNan) {
if(isSNaN)
softfloat_raiseFlags(softfloat_flag_invalid);
return defaultNaNF32UI;
} else {
float32_t res = f64_to_f32(float64_t{v1});
@ -228,11 +232,11 @@ uint32_t fconv_d2f(uint64_t v1, uint8_t mode) {
}
uint64_t fconv_f2d(uint32_t v1, uint8_t mode) {
bool nan = (v1 & defaultNaNF32UI) == defaultNaNF32UI;
if(nan) {
bool infOrNaN = expF32UI(v1) == 0xFF;
bool subnormalOrZero = expF32UI(v1) == 0;
if(infOrNaN || subnormalOrZero) {
return defaultNaNF64UI;
} else {
softfloat_roundingMode = rmm_map.at(mode);
float64_t res = f32_to_f64(float32_t{v1});
return res.v;
}
@ -312,22 +316,23 @@ uint64_t fcmp_d(uint64_t v1, uint64_t v2, uint32_t op) {
}
uint64_t fcvt_d(uint64_t v1, uint32_t op, uint8_t mode) {
float64_t v1f{v1};
softfloat_exceptionFlags = 0;
float64_t r;
switch(op) {
case 0: { // l->d, fp to int32
case 0: { // l from d
int64_t res = f64_to_i64(v1f, rmm_map.at(mode), true);
return (uint64_t)res;
}
case 1: { // lu->s
case 1: { // lu from d
uint64_t res = f64_to_ui64(v1f, rmm_map.at(mode), true);
return res;
}
case 2: // s->l
case 2: // d from l
r = i64_to_f64(v1);
return r.v;
case 3: // s->lu
case 3: // d from lu
r = ui64_to_f64(v1);
return r.v;
}
@ -335,12 +340,24 @@ uint64_t fcvt_d(uint64_t v1, uint32_t op, uint8_t mode) {
}
uint64_t fmadd_d(uint64_t v1, uint64_t v2, uint64_t v3, uint32_t op, uint8_t mode) {
// op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)}
uint64_t F64_SIGN = 1ULL << 63;
switch(op) {
case 0: // FMADD_D
break;
case 1: // FMSUB_D
v3 ^= F64_SIGN;
break;
case 2: // FNMADD_D
v1 ^= F64_SIGN;
v3 ^= F64_SIGN;
break;
case 3: // FNMSUB_D
v1 ^= F64_SIGN;
break;
}
softfloat_roundingMode = rmm_map.at(mode);
softfloat_exceptionFlags = 0;
float64_t res = softfloat_mulAddF64(v1, v2, v3, op & 0x1);
if(op > 1)
res.v ^= 1ULL << 63;
float64_t res = softfloat_mulAddF64(v1, v2, v3, 0);
return res.v;
}
@ -376,8 +393,8 @@ uint64_t fclass_d(uint64_t v1) {
uA.f = a;
uiA = uA.ui;
uint_fast16_t infOrNaN = expF64UI(uiA) == 0x7FF;
uint_fast16_t subnormalOrZero = expF64UI(uiA) == 0;
bool infOrNaN = expF64UI(uiA) == 0x7FF;
bool subnormalOrZero = expF64UI(uiA) == 0;
bool sign = signF64UI(uiA);
bool fracZero = fracF64UI(uiA) == 0;
bool isNaN = isNaNF64UI(uiA);