Skip to content

Commit 139625a

Browse files
authored
feat: adding RV64 riscv-tests suite in build and regression (#1259)
- RV64 tests for the ISS Added rv64-riscv-tests configuration Updated test:riscv-tests target with ability to build and test RV64 configuration - Corrected many instruction implementations to handle 64bit mode - Corrected the page walker and address translation - Added rv64 riscv-tests to the regression
1 parent 7e57cf3 commit 139625a

File tree

27 files changed

+353
-141
lines changed

27 files changed

+353
-141
lines changed

.github/workflows/regress.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,19 @@ jobs:
221221
uses: actions/checkout@v4
222222
- name: singularity setup
223223
uses: ./.github/actions/singularity-setup
224-
- name: Run riscv-tests
225-
run: ./do test:riscv_tests CONFIG=rv32 JOBS=4
224+
- name: Run RV32 riscv-tests
225+
run: ./do test:riscv_tests CONFIG=rv32 IGNOREUNDEFINED=YES JOBS=4
226+
regress-riscv-tests-64:
227+
runs-on: ubuntu-latest
228+
env:
229+
SINGULARITY: 1
230+
steps:
231+
- name: Clone Github Repo Action
232+
uses: actions/checkout@v4
233+
- name: singularity setup
234+
uses: ./.github/actions/singularity-setup
235+
- name: Run RV64 riscv-tests
236+
run: ./do test:riscv_tests CONFIG=rv64 IGNOREUNDEFINED=YES JOBS=4
226237
regress-xqci-doc:
227238
runs-on: ubuntu-latest
228239
env:

.vscode/launch.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"name": "ISS debug Launch",
66
"type": "cppdbg",
77
"request": "launch",
8-
"program": "${workspaceFolder}/gen/cpp_hart_gen/rv32_Debug/build/iss",
9-
"args": ["-m", "rv32", "-c", "${workspaceFolder}/cfgs/rv32-riscv-tests.yaml", "${workspaceFolder}/ext/riscv-tests/isa/rv32ui-p-addi"],
8+
"program": "${workspaceFolder}/gen/cpp_hart_gen/rv64_Debug/build/iss",
9+
"args": ["-m", "rv64", "-c", "${workspaceFolder}/cfgs/rv64-riscv-tests.yaml", "${workspaceFolder}/ext/riscv-tests/isa/rv64ui-p-addi"],
1010
"stopAtEntry": true,
1111
"cwd": "${workspaceFolder}",
1212
"environment": [],

backends/cpp_hart_gen/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ add_library(hart
118118
# ../gen/iss/oryon/src/decode.cxx
119119
)
120120
target_include_directories(hart PUBLIC ${CMAKE_SOURCE_DIR}/include)
121+
if(IGNOREUNDEFINED STREQUAL "YES")
122+
target_compile_definitions(hart PUBLIC IGNOREUNDEFINED)
123+
endif()
121124
target_link_libraries(hart PUBLIC yaml-cpp::yaml-cpp nlohmann_json_schema_validator fmt::fmt ctre::ctre -lgmp -lgmpxx)
122125

123126
# add_library(hart_c ${CMAKE_SOURCE_DIR}/src/libhart_c.cpp)
@@ -135,6 +138,9 @@ add_executable(iss
135138
${CMAKE_SOURCE_DIR}/src/iss.cpp
136139
${CMAKE_SOURCE_DIR}/src/elf_reader.cpp
137140
)
141+
if(IGNOREUNDEFINED STREQUAL "YES")
142+
target_compile_definitions(iss PUBLIC IGNOREUNDEFINED)
143+
endif()
138144
target_link_libraries(iss PRIVATE hart elf CLI11::CLI11)
139145

140146

backends/cpp_hart_gen/cpp/include/udb/bits.hpp

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ static_assert(sizeof(1ull) == 8);
6060
#error "Compiler does not support __int128"
6161
#endif
6262

63+
#ifndef IGNOREUNDEFINED
64+
#define UNDEFINED_VALUE_ERROR(s) throw UndefinedValueError(s)
65+
#else
66+
#define UNDEFINED_VALUE_ERROR(s)
67+
#endif
68+
69+
6370
namespace udb {
6471

6572
// helper to find the max of N unsigned values at compile time
@@ -694,6 +701,10 @@ namespace udb {
694701
}
695702
}
696703

704+
constexpr std::conditional_t<Signed, SignedStorageType, const StorageType &> get_ignore_unknown() const {
705+
return m_val;
706+
}
707+
697708
constexpr const _Bits& to_defined() const { return *this; }
698709

699710
// cast to other Bits types
@@ -2408,27 +2419,25 @@ namespace udb {
24082419
constexpr operator BitsType<M, _Signed>() const {
24092420
if constexpr (!BitsType<M, _Signed>::PossiblyUnknown) {
24102421
if (m_unknown_mask != 0) {
2411-
throw UndefinedValueError("Cannot convert value with unknowns to Bits type");
2422+
UNDEFINED_VALUE_ERROR("Cannot convert value with unknowns to Bits type");
24122423
}
24132424
}
24142425
return BitsType<M, _Signed>{*this};
24152426
}
24162427

24172428
template <typename T = std::conditional_t<Signed, SignedStorageType, StorageType>>
24182429
constexpr T get() const {
2419-
if (m_unknown_mask == 0_b) {
2420-
return m_val.get();
2421-
} else {
2422-
throw UndefinedValueError("Cannot convert value with unknowns to a native C++ type");
2430+
if (m_unknown_mask != 0_b) {
2431+
UNDEFINED_VALUE_ERROR("Cannot convert value with unknowns to a native C++ type");
24232432
}
2433+
return m_val.get();
24242434
}
24252435

24262436
constexpr _Bits<N, Signed> to_defined() const {
2427-
if (m_unknown_mask == 0_b) {
2428-
return m_val;
2429-
} else {
2430-
throw UndefinedValueError("Cannot convert value with unknowns to a defined type");
2437+
if (m_unknown_mask != 0_b) {
2438+
UNDEFINED_VALUE_ERROR("Cannot convert value with unknowns to a defined type");
24312439
}
2440+
return m_val;
24322441
}
24332442

24342443

@@ -2480,7 +2489,7 @@ namespace udb {
24802489
constexpr bool operator op(const BitsType<M, _Signed> &rhs) const { \
24812490
if (m_unknown_mask != 0_b || \
24822491
(BitsType<M, _Signed>::PossiblyUnknown && (rhs.unknown_mask() != 0_b))) { \
2483-
throw UndefinedValueError("Cannot compare unknown value"); \
2492+
UNDEFINED_VALUE_ERROR("Cannot compare unknown value"); \
24842493
} \
24852494
return get() op rhs.to_defined().get(); \
24862495
}
@@ -2626,7 +2635,7 @@ namespace udb {
26262635
constexpr _PossiblyUnknownBits operator<<(const BitsType<M, false> &shamt) const {
26272636
if constexpr (BitsType<M, false>::PossiblyUnknown) {
26282637
if (shamt.unknown_mask() != 0_b) {
2629-
throw UndefinedValueError("Cannot shift an unknown amount");
2638+
UNDEFINED_VALUE_ERROR("Cannot shift an unknown amount");
26302639
}
26312640
}
26322641
if (shamt.get() >= N) {
@@ -2641,7 +2650,7 @@ namespace udb {
26412650
constexpr _PossiblyUnknownBits operator>>(const BitsClass<M, false> &shamt) const {
26422651
if constexpr (BitsClass<M, false>::PossiblyUnknown) {
26432652
if (shamt.unknown_mask() != 0_b) {
2644-
throw UndefinedValueError("Cannot shift an unknown amount");
2653+
UNDEFINED_VALUE_ERROR("Cannot shift an unknown amount");
26452654
}
26462655
}
26472656
if (shamt.get() >= N) {
@@ -2656,7 +2665,7 @@ namespace udb {
26562665
constexpr _PossiblyUnknownBits sra(const BitsClass<M, false> &shamt) const {
26572666
if constexpr (BitsClass<M, false>::PossiblyUnknown) {
26582667
if (shamt.unknown_mask() != 0_b) {
2659-
throw UndefinedValueError("Cannot shift an unknown amount");
2668+
UNDEFINED_VALUE_ERROR("Cannot shift an unknown amount");
26602669
}
26612670
}
26622671
if (shamt.get() >= N) {
@@ -2715,7 +2724,7 @@ namespace udb {
27152724
_Bits<constmax_v<N, RhsN> + 1, Signed> lhs{*this};
27162725

27172726
if (m_unknown_mask != 0_b || _rhs.unknown_mask() != 0_b) {
2718-
throw UndefinedValueError("Addition is not defined on undefined values");
2727+
UNDEFINED_VALUE_ERROR("Addition is not defined on undefined values");
27192728
}
27202729

27212730
if constexpr (RhsBitsType<RhsN, RhsSigned>::RuntimeWidth) {
@@ -2738,7 +2747,7 @@ namespace udb {
27382747
_Bits<constmax_v<N, RhsN> + 1, Signed> lhs{*this};
27392748

27402749
if (m_unknown_mask != 0_b || _rhs.unknown_mask() != 0_b) {
2741-
throw UndefinedValueError("Addition is not defined on undefined values");
2750+
UNDEFINED_VALUE_ERROR("Addition is not defined on undefined values");
27422751
}
27432752

27442753
if constexpr (RhsBitsType<RhsN, RhsSigned>::RuntimeWidth) {
@@ -2767,7 +2776,7 @@ namespace udb {
27672776
_Bits<addsat_v<N, RhsN>, Signed> lhs{*this};
27682777

27692778
if (m_unknown_mask != 0_b || _rhs.unknown_mask() != 0_b) {
2770-
throw UndefinedValueError("Addition is not defined on undefined values");
2779+
UNDEFINED_VALUE_ERROR("Addition is not defined on undefined values");
27712780
}
27722781

27732782
if constexpr (RhsBitsType<RhsN, RhsSigned>::RuntimeWidth) {
@@ -3171,7 +3180,7 @@ namespace udb {
31713180
m_val, result_width};
31723181

31733182
if (unknown_mask() != 0_b || other.unknown_mask() != 0_b) {
3174-
throw UndefinedValueError("Multiplication not defined on undefined values");
3183+
UNDEFINED_VALUE_ERROR("Multiplication not defined on undefined values");
31753184
}
31763185

31773186
if constexpr (RhsBitsType<addsat_v<MaxN, RhsN>, RhsSigned>::RuntimeWidth) {
@@ -3194,7 +3203,7 @@ namespace udb {
31943203
m_val, result_width};
31953204

31963205
if (unknown_mask() != 0_b || other.unknown_mask() != 0_b) {
3197-
throw UndefinedValueError("Addition not defined on undefined values");
3206+
UNDEFINED_VALUE_ERROR("Addition not defined on undefined values");
31983207
}
31993208

32003209
if constexpr (RhsBitsType<constmax_v<MaxN, RhsN> + 1, RhsSigned>::RuntimeWidth) {
@@ -3217,7 +3226,7 @@ namespace udb {
32173226
m_val, result_width};
32183227

32193228
if (unknown_mask() != 0_b || other.unknown_mask() != 0_b) {
3220-
throw UndefinedValueError("Subtraction not defined on undefined values");
3229+
UNDEFINED_VALUE_ERROR("Subtraction not defined on undefined values");
32213230
}
32223231

32233232
if constexpr (RhsBitsType<constmax_v<MaxN, RhsN> + 1, RhsSigned>::RuntimeWidth) {
@@ -3467,7 +3476,7 @@ struct fmt::formatter<BitsClass<N, Signed>>
34673476
: formatter<typename BitsClass<N, Signed>::StorageType> {
34683477
template <typename CONTEXT_TYPE>
34693478
auto format(BitsClass<N, Signed> value, CONTEXT_TYPE &ctx) const {
3470-
return fmt::formatter<typename BitsClass<N, Signed>::StorageType>::format(value.get(), ctx);
3479+
return fmt::formatter<typename BitsClass<N, Signed>::StorageType>::format(value.get_ignore_unknown(), ctx);
34713480
}
34723481
};
34733482

backends/cpp_hart_gen/tasks.rake

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,14 @@ rule %r{#{CPP_HART_GEN_DST}/[^/]+/build/Makefile} => [
202202
"-DCONFIG_LIST=\"#{ENV['CONFIG'].gsub(',', ';')}\"",
203203
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
204204
"-DCMAKE_BUILD_TYPE=#{cmake_build_type}"
205-
].join(" ")
205+
]
206+
if ENV["IGNOREUNDEFINED"].nil?
207+
cmd.push("-DIGNOREUNDEFINED=NO")
208+
else
209+
cmd.push("-DIGNOREUNDEFINED=YES")
210+
end
206211

207-
sh cmd
212+
sh cmd.join(" ")
208213
end
209214

210215
rule %r{#{CPP_HART_GEN_DST}/[^/]+/include/udb/[^/]+\.hpp} do |t|
@@ -346,6 +351,15 @@ namespace :build do
346351
end
347352
end
348353

354+
task iss: ["gen:cpp_hart"] do
355+
_, build_name = configs_build_name
356+
357+
Rake::Task["#{CPP_HART_GEN_DST}/#{build_name}/build/Makefile"].invoke
358+
Dir.chdir("#{CPP_HART_GEN_DST}/#{build_name}/build") do
359+
sh "make -j #{$jobs} iss"
360+
end
361+
end
362+
349363
task renode_hart: ["gen:cpp_hart"] do
350364
_, build_name = configs_build_name
351365

@@ -395,7 +409,7 @@ namespace :test do
395409
end
396410
end
397411

398-
task riscv_tests: ["build_riscv_tests", "build:cpp_hart"] do
412+
task riscv_tests: ["build_riscv_tests", "build:iss"] do
399413
configs_name, build_name = configs_build_name
400414
rv32uiTests = ["simple", "add", "addi", "and",
401415
"andi", "auipc", "beq", "bge", "bgeu", "blt",
@@ -405,24 +419,62 @@ namespace :test do
405419
"sw", "st_ld", "sll", "slli", "slt", "slti",
406420
"sltiu", "sltu", "sra", "srai", "srl",
407421
"srli", "sub", "xor", "xori"]
422+
rv64uiTests = ["add", "addi", "addiw", "addw",
423+
"and", "andi",
424+
"auipc",
425+
"beq", "bge", "bgeu", "blt", "bltu", "bne",
426+
"simple",
427+
"fence_i",
428+
"jal", "jalr",
429+
"lb", "lbu", "lh", "lhu", "lw", "lwu", "ld", "ld_st",
430+
"lui",
431+
"ma_data",
432+
"or", "ori",
433+
"sb", "sh", "sw", "sd", "st_ld",
434+
"sll", "slli", "slliw", "sllw",
435+
"slt", "slti", "sltiu", "sltu",
436+
"sra", "srai", "sraiw", "sraw",
437+
"srl", "srli", "srliw", "srlw",
438+
"sub", "subw",
439+
"xor", "xori"]
440+
441+
rv32umTests = [ "div", "divu",
442+
"mul", "mulh", "mulhsu", "mulhu",
443+
"rem", "remu" ]
444+
rv64umTests = ["div", "divu", "divuw", "divw",
445+
"mul", "mulh", "mulhsu", "mulhu", "mulw",
446+
"rem", "remu", "remuw", "remw"]
447+
448+
# compressed tests same for rv32 as rv64
449+
ucTests = [ "rvc" ]
450+
451+
rv32siTests = ["csr", "dirty", "ma_fetch", "scall", "sbreak"]
452+
rv64siTests = ["csr", "dirty", "icache-alias", "ma_fetch", "scall", "sbreak"]
408453

409-
rv32uiTests.each do |t|
410-
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/rv32-riscv-tests.yaml ext/riscv-tests/isa/rv32ui-p-#{t}"
454+
if configs_name[0] == "rv64"
455+
uiTests = rv64uiTests
456+
umTests = rv64umTests
457+
siTests = rv64siTests
458+
else
459+
uiTests = rv32uiTests
460+
umTests = rv32umTests
461+
siTests = rv32siTests
411462
end
412463

413-
rv32umTests = [ "div", "divu", "mul", "mulh", "mulhsu", "mulhu", "rem", "remu" ]
414-
rv32umTests.each do |t|
415-
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/rv32-riscv-tests.yaml ext/riscv-tests/isa/rv32um-p-#{t}"
464+
uiTests.each do |t|
465+
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m #{configs_name[0]} -c #{$root}/cfgs/#{configs_name[0]}-riscv-tests.yaml ext/riscv-tests/isa/#{configs_name[0]}ui-p-#{t}"
416466
end
417467

418-
rv32ucTests = [ "rvc" ]
419-
rv32ucTests.each do |t|
420-
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/rv32-riscv-tests.yaml ext/riscv-tests/isa/rv32uc-p-#{t}"
468+
umTests.each do |t|
469+
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m #{configs_name[0]} -c #{$root}/cfgs/#{configs_name[0]}-riscv-tests.yaml ext/riscv-tests/isa/#{configs_name[0]}um-p-#{t}"
421470
end
422471

423-
rv32siTests = ["csr", "dirty", "ma_fetch", "scall", "sbreak"]
424-
rv32siTests.each do |t|
425-
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/rv32-riscv-tests.yaml ext/riscv-tests/isa/rv32si-p-#{t}"
472+
ucTests.each do |t|
473+
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m #{configs_name[0]} -c #{$root}/cfgs/#{configs_name[0]}-riscv-tests.yaml ext/riscv-tests/isa/#{configs_name[0]}uc-p-#{t}"
474+
end
475+
476+
siTests.each do |t|
477+
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m #{configs_name[0]} -c #{$root}/cfgs/#{configs_name[0]}-riscv-tests.yaml ext/riscv-tests/isa/#{configs_name[0]}si-p-#{t}"
426478
end
427479
end
428480
end

backends/cpp_hart_gen/templates/csrs.hxx.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ namespace udb {
254254
} else {
255255
udb_assert(xlen == 64_b, "Bad xlen");
256256
<%-
257-
field_cpp = fields_for_xlen32.map do |field|
257+
field_cpp = fields_for_xlen64.map do |field|
258258
if field.dynamic_location?
259259
"((m_#{field.name}._hw_read() & 0x#{((1 << field.location(64).size) - 1).to_s(16)}_b).template widening_sll<#{field.location(64).begin}>())"
260260
else

backends/cpp_hart_gen/templates/hart.hxx.erb

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -402,12 +402,9 @@ namespace udb {
402402
_set_xreg(Bits<8>{num}, Bits<MXLEN>{value});
403403
}
404404

405-
template <
406-
template <unsigned, bool> class IdxType, unsigned IdxN, bool IdxSigned,
407-
template<unsigned, bool> class ValueType, unsigned ValueN, bool ValueSigned
408-
>
409-
requires (BitsType<IdxType<IdxN, IdxSigned>> && BitsType<ValueType<ValueN, ValueSigned>>)
410-
void _set_xreg(const IdxType<IdxN, IdxSigned>& num, const ValueType<ValueN, ValueSigned>& value) {
405+
template < template <unsigned, bool> class IdxType, unsigned IdxN, bool IdxSigned >
406+
requires (BitsType<IdxType<IdxN, IdxSigned>>)
407+
void _set_xreg(const IdxType<IdxN, IdxSigned>& num, const _PossiblyUnknownBits<MXLEN, false>& value) {
411408
if (num != 0_b) {
412409
m_xregs[static_cast<unsigned>(num.get())] = value;
413410
}

0 commit comments

Comments
 (0)