Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions backends/cpp_hart_gen/cpp/include/udb/bitfield.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ namespace udb {
template <template <unsigned, bool> class BitsClass, unsigned N, bool Signed>
requires ((N >= Size) && (BitsClass<N, Signed>::IsABits))
BitfieldMember<ParentSize, Start, Size>::template operator BitsClass<N, Signed>() const {
return BitsClass<N, Signed> {static_cast<BitsType<ParentSize>>(m_parent) >> Bits<Size>(Start) & MaximumValue};
return BitsClass<N, Signed> {(static_cast<BitsType<ParentSize>>(m_parent) >> Bits<ParentSize>(Start)) & MaximumValue};
}

template <unsigned ParentSize, unsigned Start, unsigned Size>
Expand All @@ -185,7 +185,7 @@ namespace udb {
&BitfieldMember<ParentSize, Start, Size>::template operator=(
const BitfieldMember<ParentSize, Start, Size> &other) {
m_parent = (static_cast<BitsType<ParentSize>>(m_parent) & ~Mask) |
((static_cast<BitsType<Size>>(other).template widening_sll<Size>()) & Mask);
((static_cast<BitsType<Size>>(other).template widening_sll<Start>()) & Mask);
return *this;
}

Expand Down
12 changes: 7 additions & 5 deletions backends/cpp_hart_gen/cpp/include/udb/bits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2801,12 +2801,14 @@ namespace udb {
template <unsigned, bool> class MsbType, unsigned MsbN,
template <unsigned, bool> class LsbType, unsigned LsbN
>
constexpr _PossiblyUnknownBits<N, false> extract(const MsbType<MsbN, false>& msb, const LsbType<LsbN, false>& lsb) const {
constexpr _PossiblyUnknownRuntimeBits<constmax_v<MsbN, LsbN>, false> extract(const MsbType<MsbN, false>& msb, const LsbType<LsbN, false>& lsb) const {
udb_assert(msb >= lsb, "Negative range is not allowed");
udb_assert(lsb.get() <= width(), "Extract out of range");

_Bits<N, false> mask = (_Bits<N, false>{1} << (msb - lsb)) - _Bits<N, false>{1};
return _PossiblyUnknownBits<N, false>{m_val.extract(msb, lsb), m_unknown_mask.extract(msb, lsb)};
return _PossiblyUnknownRuntimeBits<constmax_v<MsbN, LsbN>, false>(
WidthArg(msb.get() - lsb.get() + 1),
ValueArg(_PossiblyUnknownBits<constmax_v<MsbN, LsbN>, false>(m_val.extract(msb, lsb), m_unknown_mask.extract(msb, lsb)))
);
}

template <unsigned Pos>
Expand Down Expand Up @@ -3018,8 +3020,8 @@ namespace udb {

constexpr explicit _PossiblyUnknownRuntimeBits(unsigned width) : m_width(width) {}
constexpr explicit _PossiblyUnknownRuntimeBits(const WidthArg& width) : m_width(width.width) {}
constexpr explicit _PossiblyUnknownRuntimeBits(const ValueArg<StorageType> val, const WidthArg& width) : m_val(val.value), m_width(width.width) {}
constexpr explicit _PossiblyUnknownRuntimeBits(const WidthArg& width, const ValueArg<StorageType> val) : m_val(val.value), m_width(width.width) {}
constexpr explicit _PossiblyUnknownRuntimeBits(const ValueArg<_PossiblyUnknownBits<MaxN, Signed>> val, const WidthArg& width) : m_val(val.value), m_width(width.width) {}
constexpr explicit _PossiblyUnknownRuntimeBits(const WidthArg& width, const ValueArg<_PossiblyUnknownBits<MaxN, Signed>> val) : m_val(val.value), m_width(width.width) {}

// template <std::integral T>
// constexpr _PossiblyUnknownRuntimeBits(const T &initial_value, unsigned width)
Expand Down
35 changes: 25 additions & 10 deletions backends/cpp_hart_gen/tasks.rake
Original file line number Diff line number Diff line change
Expand Up @@ -397,17 +397,32 @@ namespace :test do

task riscv_tests: ["build_riscv_tests", "build:cpp_hart"] do
configs_name, build_name = configs_build_name
tests = ["simple", "add", "addi", "and",
"andi", "auipc", "beq", "bge", "bgeu", "blt",
"bltu", "bne", "fence_i", "jal", "jalr",
"lb", "lbu", "lh", "lhu", "lw", "ld_st",
"lui", "ma_data", "or", "ori", "sb", "sh",
"sw", "st_ld", "sll", "slli", "slt", "slti",
"sltiu", "sltu", "sra", "srai", "srl",
"srli", "sub", "xor", "xori"]

tests.each do |t|
rv32uiTests = ["simple", "add", "addi", "and",
"andi", "auipc", "beq", "bge", "bgeu", "blt",
"bltu", "bne", "fence_i", "jal", "jalr",
"lb", "lbu", "lh", "lhu", "lw", "ld_st",
"lui", "ma_data", "or", "ori", "sb", "sh",
"sw", "st_ld", "sll", "slli", "slt", "slti",
"sltiu", "sltu", "sra", "srai", "srl",
"srli", "sub", "xor", "xori"]

rv32uiTests.each do |t|
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/mc100-32-riscv-tests.yaml ext/riscv-tests/isa/rv32ui-p-#{t}"
end

rv32umTests = [ "div", "divu", "mul", "mulh", "mulhsu", "mulhu", "rem", "remu" ]
rv32umTests.each do |t|
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/mc100-32-riscv-tests.yaml ext/riscv-tests/isa/rv32um-p-#{t}"
end

rv32ucTests = [ "rvc" ]
rv32ucTests.each do |t|
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/mc100-32-riscv-tests.yaml ext/riscv-tests/isa/rv32uc-p-#{t}"
end

rv32siTests = ["csr", "dirty", "ma_fetch", "scall", "sbreak"]
rv32siTests.each do |t|
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/mc100-32-riscv-tests.yaml ext/riscv-tests/isa/rv32si-p-#{t}"
end
end
end
2 changes: 1 addition & 1 deletion backends/cpp_hart_gen/templates/enum.hxx.erb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace udb {
}

constexpr bool operator!=(const <%= enum.name %>& rhs) const {
return m_value == rhs.m_value;
return m_value != rhs.m_value;
}

constexpr bool operator<(const <%= enum.name %>& rhs) const {
Expand Down
9 changes: 9 additions & 0 deletions backends/cpp_hart_gen/templates/hart_impl.hxx.erb
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,20 @@ namespace udb {
for (unsigned b = 0; b < bb_size; b++) {
inst = current_bb->pop();

fmt::print("PC {:x} {}\n", m_pc, inst->disassemble());
for (auto r : inst->srcRegs()) {
fmt::print("R {} {:x}\n", r.to_string(), _xreg(r.get_num()));
}

// set the fall-through next pc
m_next_pc = m_pc + Bits<MXLEN>{inst->enc_len()};

inst->execute();

for (auto r : inst->dstRegs()) {
fmt::print("R= {} {:x}\n", r.to_string(), _xreg(r.get_num()));
}

advance_pc();
if (this->m_exit_requested) {
this->m_exit_requested = false; // reset the request
Expand Down
3 changes: 2 additions & 1 deletion cfgs/mc100-32-riscv-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ implemented_extensions:
- [Smpmp, "1.11.0"]
- [U, "1.0.0"]
- [Zifencei, "2.0.0"]
- [Sv32, "1.11.0"]

params:
MXLEN: 32
Expand Down Expand Up @@ -108,7 +109,7 @@ params:
false,
false,
]
STVEC_MODE_DIRECT: false
STVEC_MODE_DIRECT: true
STVEC_MODE_VECTORED: true
SATP_MODE_BARE: true
TRAP_ON_ECALL_FROM_S: true
Expand Down
49 changes: 30 additions & 19 deletions spec/std/isa/csr/satp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,28 +45,39 @@ fields:
reset_value(): |
return 0;
sw_write(csr_value): |
if (SATP_MODE_BARE) {
if (csr_value.MODE == 0) {
# In Bare, ASID and PPN must be zero, else the entire write is ignored
if (csr_value.ASID == 0 && csr_value.PPN == 0) {
if (CSR[satp].MODE != 0) {
# changes *to* Bare mode take effect immediately without needing sfence.vma
# thus, an implicit sfence.vma occurs now
VmaOrderType order_type;
order_type.global = true;
order_pgtbl_writes_before_vmafence(order_type);

invalidate_translations(order_type);

order_pgtbl_reads_after_vmafence(order_type);
}
return csr_value.MODE;
} else {
return UNDEFINED_LEGAL_DETERMINISTIC;
if (SATP_MODE_BARE && (csr_value.MODE == 0)) {
# In Bare, ASID and PPN must be zero, else the entire write is ignored
if (csr_value.ASID == 0 && csr_value.PPN == 0) {
if (CSR[satp].MODE != 0) {
# changes *to* Bare mode take effect immediately without needing sfence.vma
# thus, an implicit sfence.vma occurs now
VmaOrderType order_type;
order_type.global = true;
order_pgtbl_writes_before_vmafence(order_type);

invalidate_translations(order_type);

order_pgtbl_reads_after_vmafence(order_type);
}
return csr_value.MODE;
} else {
return UNDEFINED_LEGAL_DETERMINISTIC;
}
}
else if (implemented?(ExtensionName::Sv39) && csr_value.MODE == 8) {
else if (implemented?(ExtensionName::Sv32) && csr_value.MODE == 1) {
if (CSR[satp].MODE == 0) {
# changes *from* Bare mode take effect immediately without needing sfence.vma
# thus, an implicit sfence.vma occurs now
VmaOrderType order_type;
order_type.global = true;
order_pgtbl_writes_before_vmafence(order_type);

invalidate_translations(order_type);

order_pgtbl_reads_after_vmafence(order_type);
}
return csr_value.MODE;
}else if (implemented?(ExtensionName::Sv39) && csr_value.MODE == 8) {
if (CSR[satp].MODE == 0) {
# changes *from* Bare mode take effect immediately without needing sfence.vma
# thus, an implicit sfence.vma occurs now
Expand Down
18 changes: 15 additions & 3 deletions spec/std/isa/inst/S/sret.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ operation(): |
}
}
} else {
if (mode() != PrivilegeMode::U) {
if (mode() == PrivilegeMode::U) {
raise (ExceptionCode::IllegalInstruction, mode(), $encoding);
}
}
Expand All @@ -107,13 +107,25 @@ operation(): |
if (!virtual_mode?()) {
if (implemented?(ExtensionName::H)) {
if (CSR[hstatus].SPV == 1'b1) {
if (CSR[mstatus].SPP == 2'b01) {
if (CSR[mstatus].SPP == 1'b1) {
set_mode(PrivilegeMode::VS);
} else if (CSR[mstatus].SPP == 2'b00) {
} else {
set_mode(PrivilegeMode::VU);
}
} else {
if (CSR[mstatus].SPP == 1'b1) {
set_mode(PrivilegeMode::S);
} else {
set_mode(PrivilegeMode::U);
}
}
CSR[hstatus].SPV = 0;
} else {
if (CSR[mstatus].SPP == 1'b1) {
set_mode(PrivilegeMode::S);
} else {
set_mode(PrivilegeMode::U);
}
}
CSR[mstatus].SIE = CSR[mstatus].SPIE;
CSR[mstatus].SPIE = 1;
Expand Down
Loading
Loading