[Testing] Get tests running (dirty hack for linux)
This commit is contained in:
@@ -91,7 +91,7 @@ DEFINE_bool(mount_scratch, false, "Enable scratch mount", "Storage");
|
|||||||
DEFINE_bool(mount_cache, true, "Enable cache mount", "Storage");
|
DEFINE_bool(mount_cache, true, "Enable cache mount", "Storage");
|
||||||
UPDATE_from_bool(mount_cache, 2024, 8, 31, 20, false);
|
UPDATE_from_bool(mount_cache, 2024, 8, 31, 20, false);
|
||||||
|
|
||||||
DEFINE_bool(force_mount_devkit, false, "Force devkit mount", "Storage");
|
DECLARE_bool(force_mount_devkit);
|
||||||
|
|
||||||
DEFINE_transient_path(target, "",
|
DEFINE_transient_path(target, "",
|
||||||
"Specifies the target .xex or .iso to execute.",
|
"Specifies the target .xex or .iso to execute.",
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ namespace amd64 {
|
|||||||
static uint64_t g_feature_flags = 0U;
|
static uint64_t g_feature_flags = 0U;
|
||||||
static bool g_did_initialize_feature_flags = false;
|
static bool g_did_initialize_feature_flags = false;
|
||||||
uint64_t GetFeatureFlags() {
|
uint64_t GetFeatureFlags() {
|
||||||
xenia_assert(g_did_initialize_feature_flags);
|
if (!g_did_initialize_feature_flags) {
|
||||||
|
InitFeatureFlags();
|
||||||
|
}
|
||||||
return g_feature_flags;
|
return g_feature_flags;
|
||||||
}
|
}
|
||||||
XE_COLD
|
XE_COLD
|
||||||
|
|||||||
@@ -1185,7 +1185,12 @@ static bool IsPossibleMMIOInstruction(X64Emitter& e, const hir::Instr* i) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto flags = e.GuestModule()->GetInstructionAddressFlags(guestaddr);
|
auto guest_module = e.GuestModule();
|
||||||
|
if (!guest_module) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto flags = guest_module->GetInstructionAddressFlags(guestaddr);
|
||||||
|
|
||||||
return flags && flags->accessed_mmio;
|
return flags && flags->accessed_mmio;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ test_vmaddfp_1:
|
|||||||
# 1.0, 1.5, 1.1, 1.9
|
# 1.0, 1.5, 1.1, 1.9
|
||||||
vmaddfp v3, v4, v4, v4
|
vmaddfp v3, v4, v4, v4
|
||||||
blr
|
blr
|
||||||
#_ REGISTER_OUT v3 [40000000, 40700000, 4013d70a, 40b051eb]
|
#_ REGISTER_OUT v3 [40000000, 40700000, 4013d70b, 40b051eb]
|
||||||
#_ REGISTER_OUT v4 [3f800000, 3fc00000, 3f8ccccd, 3ff33333]
|
#_ REGISTER_OUT v4 [3f800000, 3fc00000, 3f8ccccd, 3ff33333]
|
||||||
# 2.0, 3.75, 2.31, 5.51
|
# 2.0, 3.75, 2.31, 5.51
|
||||||
# 40b051eb is actually 5.50999975, not 5.51?
|
# 40b051eb is actually 5.50999975, not 5.51?
|
||||||
|
|||||||
@@ -27,6 +27,9 @@
|
|||||||
|
|
||||||
#if XE_COMPILER_MSVC
|
#if XE_COMPILER_MSVC
|
||||||
#include "xenia/base/platform_win.h"
|
#include "xenia/base/platform_win.h"
|
||||||
|
#else
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
#endif // XE_COMPILER_MSVC
|
#endif // XE_COMPILER_MSVC
|
||||||
|
|
||||||
DEFINE_path(test_path, "src/xenia/cpu/ppc/testing/",
|
DEFINE_path(test_path, "src/xenia/cpu/ppc/testing/",
|
||||||
@@ -191,6 +194,10 @@ class TestRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Setup(TestSuite& suite) {
|
bool Setup(TestSuite& suite) {
|
||||||
|
// Reset thread state first so it can properly deinitialize with the
|
||||||
|
// existing processor before we destroy the processor.
|
||||||
|
thread_state_.reset();
|
||||||
|
|
||||||
// Reset memory.
|
// Reset memory.
|
||||||
memory_->Reset();
|
memory_->Reset();
|
||||||
|
|
||||||
@@ -245,14 +252,17 @@ class TestRunner {
|
|||||||
bool Run(TestCase& test_case) {
|
bool Run(TestCase& test_case) {
|
||||||
// Setup test state from annotations.
|
// Setup test state from annotations.
|
||||||
if (!SetupTestState(test_case)) {
|
if (!SetupTestState(test_case)) {
|
||||||
XELOGE("Test setup failed");
|
fprintf(stderr, " [%s] Test setup failed\n", test_case.name.c_str());
|
||||||
|
fflush(stderr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute test.
|
// Execute test.
|
||||||
auto fn = processor_->ResolveFunction(test_case.address);
|
auto fn = processor_->ResolveFunction(test_case.address);
|
||||||
if (!fn) {
|
if (!fn) {
|
||||||
XELOGE("Entry function not found");
|
fprintf(stderr, " [%s] Entry function not found\n",
|
||||||
|
test_case.name.c_str());
|
||||||
|
fflush(stderr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,9 +326,13 @@ class TestRunner {
|
|||||||
if (!ppc_context->CompareRegWithString(
|
if (!ppc_context->CompareRegWithString(
|
||||||
reg_name.c_str(), reg_value.c_str(), actual_value)) {
|
reg_name.c_str(), reg_value.c_str(), actual_value)) {
|
||||||
any_failed = true;
|
any_failed = true;
|
||||||
XELOGE("Register {} assert failed:\n", reg_name);
|
fprintf(stderr, " [%s] Register %s assert failed:\n",
|
||||||
XELOGE(" Expected: {} == {}\n", reg_name, reg_value);
|
test_case.name.c_str(), reg_name.c_str());
|
||||||
XELOGE(" Actual: {} == {}\n", reg_name, actual_value);
|
fprintf(stderr, " Expected: %s == %s\n", reg_name.c_str(),
|
||||||
|
reg_value.c_str());
|
||||||
|
fprintf(stderr, " Actual: %s == %s\n", reg_name.c_str(),
|
||||||
|
actual_value.c_str());
|
||||||
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
} else if (it.first == "MEMORY_OUT") {
|
} else if (it.first == "MEMORY_OUT") {
|
||||||
size_t space_pos = it.second.find(" ");
|
size_t space_pos = it.second.find(" ");
|
||||||
@@ -355,9 +369,11 @@ class TestRunner {
|
|||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
if (failed) {
|
if (failed) {
|
||||||
XELOGE("Memory {} assert failed:\n", address_str);
|
fprintf(stderr, " [%s] Memory %s assert failed:\n",
|
||||||
XELOGE(" Expected:{}\n", expecteds.to_string());
|
test_case.name.c_str(), address_str.c_str());
|
||||||
XELOGE(" Actual:{}\n", actuals.to_string());
|
fprintf(stderr, " Expected:%s\n", expecteds.to_string().c_str());
|
||||||
|
fprintf(stderr, " Actual:%s\n", actuals.to_string().c_str());
|
||||||
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -375,9 +391,13 @@ bool DiscoverTests(const std::filesystem::path& test_path,
|
|||||||
auto file_infos = xe::filesystem::ListFiles(test_path);
|
auto file_infos = xe::filesystem::ListFiles(test_path);
|
||||||
for (auto& file_info : file_infos) {
|
for (auto& file_info : file_infos) {
|
||||||
if (file_info.name.extension() == ".s") {
|
if (file_info.name.extension() == ".s") {
|
||||||
|
// Only include test files (instr_*.s), not helper files
|
||||||
|
auto filename = file_info.name.filename().string();
|
||||||
|
if (filename.find("instr_") == 0) {
|
||||||
test_files.push_back(test_path / file_info.name);
|
test_files.push_back(test_path / file_info.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,27 +410,128 @@ int filter(unsigned int code) {
|
|||||||
}
|
}
|
||||||
#endif // XE_COMPILER_MSVC
|
#endif // XE_COMPILER_MSVC
|
||||||
|
|
||||||
|
#if !XE_COMPILER_MSVC
|
||||||
|
// Run test in isolated child process to catch crashes
|
||||||
|
enum class TestResult {
|
||||||
|
kPassed,
|
||||||
|
kFailed,
|
||||||
|
kCrashed,
|
||||||
|
};
|
||||||
|
|
||||||
|
TestResult RunTestInChildProcess(TestSuite& test_suite, TestCase& test_case) {
|
||||||
|
pid_t pid = fork();
|
||||||
|
|
||||||
|
if (pid == -1) {
|
||||||
|
// Fork failed
|
||||||
|
fprintf(stderr, " [%s] TEST FAILED (fork failed)\n",
|
||||||
|
test_case.name.c_str());
|
||||||
|
fflush(stderr);
|
||||||
|
return TestResult::kFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid == 0) {
|
||||||
|
// Child process - create a fresh TestRunner to avoid inherited state issues
|
||||||
|
TestRunner child_runner;
|
||||||
|
if (!child_runner.Setup(test_suite)) {
|
||||||
|
_exit(2); // Setup failure
|
||||||
|
}
|
||||||
|
if (child_runner.Run(test_case)) {
|
||||||
|
_exit(0); // Test passed
|
||||||
|
} else {
|
||||||
|
_exit(1); // Test failed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parent process - wait for child
|
||||||
|
int status;
|
||||||
|
pid_t result = waitpid(pid, &status, 0);
|
||||||
|
|
||||||
|
if (result == -1) {
|
||||||
|
fprintf(stderr, " [%s] TEST FAILED (waitpid failed, pid %d)\n",
|
||||||
|
test_case.name.c_str(), pid);
|
||||||
|
fflush(stderr);
|
||||||
|
return TestResult::kFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WIFEXITED(status)) {
|
||||||
|
int exit_code = WEXITSTATUS(status);
|
||||||
|
if (exit_code == 0) {
|
||||||
|
// Test passed - don't print anything
|
||||||
|
return TestResult::kPassed;
|
||||||
|
} else if (exit_code == 2) {
|
||||||
|
fprintf(stderr, " [%s] FAILED SETUP (exit code %d)\n",
|
||||||
|
test_case.name.c_str(), exit_code);
|
||||||
|
fflush(stderr);
|
||||||
|
return TestResult::kFailed;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, " [%s] FAILED (exit code %d)\n", test_case.name.c_str(),
|
||||||
|
exit_code);
|
||||||
|
fflush(stderr);
|
||||||
|
return TestResult::kFailed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WIFSIGNALED(status)) {
|
||||||
|
int signal = WTERMSIG(status);
|
||||||
|
const char* signal_name = "UNKNOWN";
|
||||||
|
switch (signal) {
|
||||||
|
case SIGSEGV:
|
||||||
|
signal_name = "SIGSEGV";
|
||||||
|
break;
|
||||||
|
case SIGILL:
|
||||||
|
signal_name = "SIGILL";
|
||||||
|
break;
|
||||||
|
case SIGFPE:
|
||||||
|
signal_name = "SIGFPE";
|
||||||
|
break;
|
||||||
|
case SIGBUS:
|
||||||
|
signal_name = "SIGBUS";
|
||||||
|
break;
|
||||||
|
case SIGABRT:
|
||||||
|
signal_name = "SIGABRT";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(stderr, " [%s] CRASHED (%s)\n", test_case.name.c_str(),
|
||||||
|
signal_name);
|
||||||
|
fflush(stderr);
|
||||||
|
return TestResult::kCrashed;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, " [%s] FAILED (unknown reason)\n", test_case.name.c_str());
|
||||||
|
fflush(stderr);
|
||||||
|
return TestResult::kFailed;
|
||||||
|
}
|
||||||
|
#endif // !XE_COMPILER_MSVC
|
||||||
|
|
||||||
void ProtectedRunTest(TestSuite& test_suite, TestRunner& runner,
|
void ProtectedRunTest(TestSuite& test_suite, TestRunner& runner,
|
||||||
TestCase& test_case, int& failed_count,
|
TestCase& test_case, int& failed_count,
|
||||||
int& passed_count) {
|
int& passed_count) {
|
||||||
#if XE_COMPILER_MSVC
|
#if XE_COMPILER_MSVC
|
||||||
__try {
|
__try {
|
||||||
#endif // XE_COMPILER_MSVC
|
|
||||||
|
|
||||||
if (!runner.Setup(test_suite)) {
|
if (!runner.Setup(test_suite)) {
|
||||||
XELOGE(" TEST FAILED SETUP");
|
XELOGE(" [{}] TEST FAILED SETUP", test_case.name);
|
||||||
++failed_count;
|
++failed_count;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (runner.Run(test_case)) {
|
if (runner.Run(test_case)) {
|
||||||
++passed_count;
|
++passed_count;
|
||||||
} else {
|
} else {
|
||||||
XELOGE(" TEST FAILED");
|
XELOGE(" [{}] TEST FAILED", test_case.name);
|
||||||
++failed_count;
|
++failed_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if XE_COMPILER_MSVC
|
|
||||||
} __except (filter(GetExceptionCode())) {
|
} __except (filter(GetExceptionCode())) {
|
||||||
XELOGE(" TEST FAILED (UNSUPPORTED INSTRUCTION)");
|
XELOGE(" [{}] TEST FAILED (UNSUPPORTED INSTRUCTION)", test_case.name);
|
||||||
|
++failed_count;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Use fork to isolate crashes on POSIX systems
|
||||||
|
// Note: runner parameter is not used on POSIX
|
||||||
|
(void)runner; // Suppress unused parameter warning
|
||||||
|
TestResult result = RunTestInChildProcess(test_suite, test_case);
|
||||||
|
|
||||||
|
if (result == TestResult::kPassed) {
|
||||||
|
++passed_count;
|
||||||
|
} else {
|
||||||
++failed_count;
|
++failed_count;
|
||||||
}
|
}
|
||||||
#endif // XE_COMPILER_MSVC
|
#endif // XE_COMPILER_MSVC
|
||||||
@@ -456,23 +577,27 @@ bool RunTests(const std::string_view test_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
XELOGI("{} tests loaded.", test_suites.size());
|
XELOGI("{} tests loaded.", test_suites.size());
|
||||||
|
#if XE_COMPILER_MSVC
|
||||||
|
// On Windows, use a single shared test runner
|
||||||
TestRunner runner;
|
TestRunner runner;
|
||||||
|
#else
|
||||||
|
// On POSIX, each test will create its own runner in a forked process
|
||||||
|
// Pass a dummy value that won't be used
|
||||||
|
TestRunner* runner_ptr = nullptr;
|
||||||
|
TestRunner& runner = *runner_ptr; // Never dereferenced on POSIX
|
||||||
|
#endif
|
||||||
for (auto& test_suite : test_suites) {
|
for (auto& test_suite : test_suites) {
|
||||||
XELOGI("{}.s:", test_suite.name());
|
|
||||||
|
|
||||||
for (auto& test_case : test_suite.test_cases()) {
|
for (auto& test_case : test_suite.test_cases()) {
|
||||||
XELOGI(" - {}", test_case.name);
|
|
||||||
ProtectedRunTest(test_suite, runner, test_case, failed_count,
|
ProtectedRunTest(test_suite, runner, test_case, failed_count,
|
||||||
passed_count);
|
passed_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
XELOGI("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XELOGI("");
|
fprintf(stderr, "\n");
|
||||||
XELOGI("Total tests: {}", failed_count + passed_count);
|
fprintf(stderr, "Total tests: %d\n", failed_count + passed_count);
|
||||||
XELOGI("Passed: {}", passed_count);
|
fprintf(stderr, "Passed: %d\n", passed_count);
|
||||||
XELOGI("Failed: {}", failed_count);
|
fprintf(stderr, "Failed: %d\n", failed_count);
|
||||||
|
fflush(stderr);
|
||||||
|
|
||||||
return failed_count ? false : true;
|
return failed_count ? false : true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -411,9 +411,12 @@ bool DiscoverTests(std::wstring& test_path,
|
|||||||
for (auto& file_info : file_infos) {
|
for (auto& file_info : file_infos) {
|
||||||
if (file_info.name != L"." && file_info.name != L".." &&
|
if (file_info.name != L"." && file_info.name != L".." &&
|
||||||
file_info.name.rfind(L".s") == file_info.name.size() - 2) {
|
file_info.name.rfind(L".s") == file_info.name.size() - 2) {
|
||||||
|
// Only include test files (instr_*.s), not helper files
|
||||||
|
if (file_info.name.find(L"instr_") == 0) {
|
||||||
test_files.push_back(xe::join_paths(test_path, file_info.name));
|
test_files.push_back(xe::join_paths(test_path, file_info.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,17 +7,25 @@ project("xenia-cpu-ppc-tests")
|
|||||||
kind("ConsoleApp")
|
kind("ConsoleApp")
|
||||||
language("C++")
|
language("C++")
|
||||||
links({
|
links({
|
||||||
"capstone", -- cpu-backend-x64
|
"xenia-apu",
|
||||||
"fmt",
|
"xenia-apu-nop",
|
||||||
"mspack",
|
"xenia-base",
|
||||||
"imgui",
|
|
||||||
"xenia-core",
|
"xenia-core",
|
||||||
"xenia-cpu",
|
"xenia-cpu",
|
||||||
"xenia-gpu",
|
"xenia-gpu",
|
||||||
"xenia-base",
|
"xenia-gpu-null",
|
||||||
|
"xenia-hid",
|
||||||
|
"xenia-hid-nop",
|
||||||
"xenia-kernel",
|
"xenia-kernel",
|
||||||
"xenia-patcher",
|
"xenia-patcher",
|
||||||
"xenia-hid-skylander",
|
"xenia-ui",
|
||||||
|
"xenia-vfs",
|
||||||
|
})
|
||||||
|
links({
|
||||||
|
"capstone",
|
||||||
|
"fmt",
|
||||||
|
"imgui",
|
||||||
|
"mspack",
|
||||||
})
|
})
|
||||||
files({
|
files({
|
||||||
"ppc_testing_main.cc",
|
"ppc_testing_main.cc",
|
||||||
@@ -41,10 +49,7 @@ project("xenia-cpu-ppc-tests")
|
|||||||
"1>scratch/stdout-testing.txt",
|
"1>scratch/stdout-testing.txt",
|
||||||
})
|
})
|
||||||
|
|
||||||
-- xenia-base needs this
|
filter({})
|
||||||
links({
|
|
||||||
"xenia-ui",
|
|
||||||
})
|
|
||||||
|
|
||||||
if ARCH == "ppc64" or ARCH == "powerpc64" then
|
if ARCH == "ppc64" or ARCH == "powerpc64" then
|
||||||
|
|
||||||
|
|||||||
@@ -85,8 +85,13 @@ Symbol::Status TestModule::DeclareFunction(uint32_t address,
|
|||||||
// Reset() all caching when we leave.
|
// Reset() all caching when we leave.
|
||||||
xe::make_reset_scope(compiler_);
|
xe::make_reset_scope(compiler_);
|
||||||
xe::make_reset_scope(assembler_);
|
xe::make_reset_scope(assembler_);
|
||||||
|
xe::make_reset_scope(builder_);
|
||||||
|
|
||||||
|
// Set the HIRBuilder as current for this thread
|
||||||
|
builder_->MakeCurrent();
|
||||||
|
|
||||||
if (!generate_(*builder_.get())) {
|
if (!generate_(*builder_.get())) {
|
||||||
|
builder_->RemoveCurrent();
|
||||||
function->set_status(Symbol::Status::kFailed);
|
function->set_status(Symbol::Status::kFailed);
|
||||||
return Symbol::Status::kFailed;
|
return Symbol::Status::kFailed;
|
||||||
}
|
}
|
||||||
@@ -97,6 +102,9 @@ Symbol::Status TestModule::DeclareFunction(uint32_t address,
|
|||||||
// Assemble the function.
|
// Assemble the function.
|
||||||
assembler_->Assemble(function, builder_.get(), 0, nullptr);
|
assembler_->Assemble(function, builder_.get(), 0, nullptr);
|
||||||
|
|
||||||
|
// Remove the HIRBuilder as current for this thread
|
||||||
|
builder_->RemoveCurrent();
|
||||||
|
|
||||||
status = Symbol::Status::kDefined;
|
status = Symbol::Status::kDefined;
|
||||||
function->set_status(status);
|
function->set_status(status);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
DECLARE_bool(debug);
|
DECLARE_bool(debug);
|
||||||
|
|
||||||
DECLARE_bool(force_mount_devkit);
|
DEFINE_bool(force_mount_devkit, false, "Force devkit mount", "Storage");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|||||||
@@ -28,9 +28,14 @@ XbdmModule::XbdmModule(Emulator* emulator, KernelState* kernel_state)
|
|||||||
#undef XE_MODULE_EXPORT_GROUP
|
#undef XE_MODULE_EXPORT_GROUP
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<xe::cpu::Export*> xbdm_exports(4096);
|
// Use construct-on-first-use idiom to avoid static initialization order issues
|
||||||
|
std::vector<xe::cpu::Export*>& GetXbdmExports() {
|
||||||
|
static std::vector<xe::cpu::Export*> xbdm_exports(4096);
|
||||||
|
return xbdm_exports;
|
||||||
|
}
|
||||||
|
|
||||||
xe::cpu::Export* RegisterExport_xbdm(xe::cpu::Export* export_entry) {
|
xe::cpu::Export* RegisterExport_xbdm(xe::cpu::Export* export_entry) {
|
||||||
|
auto& xbdm_exports = GetXbdmExports();
|
||||||
assert_true(export_entry->ordinal < xbdm_exports.size());
|
assert_true(export_entry->ordinal < xbdm_exports.size());
|
||||||
xbdm_exports[export_entry->ordinal] = export_entry;
|
xbdm_exports[export_entry->ordinal] = export_entry;
|
||||||
return export_entry;
|
return export_entry;
|
||||||
@@ -45,6 +50,7 @@ void XbdmModule::RegisterExportTable(xe::cpu::ExportResolver* export_resolver) {
|
|||||||
#include "xenia/kernel/xbdm/xbdm_table.inc"
|
#include "xenia/kernel/xbdm/xbdm_table.inc"
|
||||||
};
|
};
|
||||||
#include "xenia/kernel/util/export_table_post.inc"
|
#include "xenia/kernel/util/export_table_post.inc"
|
||||||
|
auto& xbdm_exports = GetXbdmExports();
|
||||||
for (size_t i = 0; i < xe::countof(xbdm_export_table); ++i) {
|
for (size_t i = 0; i < xe::countof(xbdm_export_table); ++i) {
|
||||||
auto& export_entry = xbdm_export_table[i];
|
auto& export_entry = xbdm_export_table[i];
|
||||||
assert_true(export_entry.ordinal < xbdm_exports.size());
|
assert_true(export_entry.ordinal < xbdm_exports.size());
|
||||||
|
|||||||
2
third_party/binutils/build.sh
vendored
2
third_party/binutils/build.sh
vendored
@@ -21,7 +21,7 @@ SNAPSHOT_FILE=binutils-$SNAPSHOT_VERSION.tar.gz
|
|||||||
if [ ! -f $SNAPSHOT_FILE ]; then
|
if [ ! -f $SNAPSHOT_FILE ]; then
|
||||||
echo ""
|
echo ""
|
||||||
echo "Grabbing binutils snapshot $SNAPSHOT_FILE..."
|
echo "Grabbing binutils snapshot $SNAPSHOT_FILE..."
|
||||||
curl -nv http://mirrors.kernel.org/sourceware/binutils/releases/$SNAPSHOT_FILE > $SNAPSHOT_FILE
|
curl -L http://mirrors.kernel.org/sourceware/binutils/releases/$SNAPSHOT_FILE -o $SNAPSHOT_FILE
|
||||||
else
|
else
|
||||||
echo ""
|
echo ""
|
||||||
echo "Reusing existing binutils snapshot file $SNAPSHOT_FILE..."
|
echo "Reusing existing binutils snapshot file $SNAPSHOT_FILE..."
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "xenia/base/console_app_main.h"
|
#include "xenia/base/console_app_main.h"
|
||||||
#include "xenia/base/cvar.h"
|
#include "xenia/base/cvar.h"
|
||||||
|
#include "xenia/base/platform.h"
|
||||||
|
|
||||||
#define CATCH_CONFIG_RUNNER
|
#define CATCH_CONFIG_RUNNER
|
||||||
#include "third_party/catch/single_include/catch2/catch.hpp"
|
#include "third_party/catch/single_include/catch2/catch.hpp"
|
||||||
|
|||||||
@@ -539,7 +539,7 @@ def run_premake(target_os, action, cc=None):
|
|||||||
os.path.join("tools", "build", "premake.py"),
|
os.path.join("tools", "build", "premake.py"),
|
||||||
"--file=premake5.lua",
|
"--file=premake5.lua",
|
||||||
f"--os={target_os}",
|
f"--os={target_os}",
|
||||||
#"--test-suite-mode=combined",
|
"--test-suite-mode=combined",
|
||||||
"--verbose",
|
"--verbose",
|
||||||
action,
|
action,
|
||||||
]
|
]
|
||||||
@@ -1218,12 +1218,20 @@ class TestCommand(BaseBuildCommand):
|
|||||||
print_error(f"Unable to find {test_targets[i]} - build it.")
|
print_error(f"Unable to find {test_targets[i]} - build it.")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
# Prepare environment with Qt bin directory in PATH if available
|
||||||
|
test_env = dict(os.environ)
|
||||||
|
qt_dir = os.environ.get("QT_DIR")
|
||||||
|
if qt_dir and sys.platform == "win32":
|
||||||
|
qt_bin = os.path.join(qt_dir, "bin")
|
||||||
|
if os.path.exists(qt_bin):
|
||||||
|
test_env["PATH"] = f"{qt_bin}{os.pathsep}{test_env['PATH']}"
|
||||||
|
print(f"- Qt bin directory added to PATH: {qt_bin}\n")
|
||||||
|
|
||||||
# Run tests.
|
# Run tests.
|
||||||
any_failed = False
|
any_failed = False
|
||||||
for test_executable in test_executables:
|
for test_executable in test_executables:
|
||||||
print(f"- {test_executable}")
|
print(f"- {test_executable}")
|
||||||
result = shell_call([test_executable] + pass_args,
|
result = subprocess.call([test_executable] + pass_args, env=test_env)
|
||||||
throw_on_error=False)
|
|
||||||
if result:
|
if result:
|
||||||
any_failed = True
|
any_failed = True
|
||||||
if args["continue"]:
|
if args["continue"]:
|
||||||
|
|||||||
Reference in New Issue
Block a user