diff --git a/src/alloy/frontend/ppc/ppc_context.cc b/src/alloy/frontend/ppc/ppc_context.cc index 6bb9fea2b..9495cabf8 100644 --- a/src/alloy/frontend/ppc/ppc_context.cc +++ b/src/alloy/frontend/ppc/ppc_context.cc @@ -19,10 +19,26 @@ uint64_t ParseInt64(const char* value) { return std::strtoull(value, nullptr, 0); } +vec128_t ParseVec128(const char* value) { + vec128_t v; + char* p = const_cast(value); + if (*p == '[') ++p; + v.i32[0] = std::strtoul(p, &p, 16); + while (*p == ' ' || *p == ',') ++p; + v.i32[1] = std::strtoul(p, &p, 16); + while (*p == ' ' || *p == ',') ++p; + v.i32[2] = std::strtoul(p, &p, 16); + while (*p == ' ' || *p == ',') ++p; + v.i32[3] = std::strtoul(p, &p, 16); + return v; +} + void PPCContext::SetRegFromString(const char* name, const char* value) { int n; if (sscanf(name, "r%d", &n) == 1) { this->r[n] = ParseInt64(value); + } else if (sscanf(name, "v%d", &n) == 1) { + this->v[n] = ParseVec128(value); } else { printf("Unrecognized register name: %s\n", name); } @@ -38,6 +54,15 @@ bool PPCContext::CompareRegWithString(const char* name, const char* value, return false; } return true; + } else if (sscanf(name, "v%d", &n) == 1) { + vec128_t expected = ParseVec128(value); + if (this->v[n] != expected) { + snprintf(out_value, out_value_size, "[%.8X, %.8X, %.8X, %.8X]", + this->v[n].i32[0], this->v[n].i32[1], this->v[n].i32[2], + this->v[n].i32[3]); + return false; + } + return true; } else { printf("Unrecognized register name: %s\n", name); return false; diff --git a/src/alloy/frontend/ppc/test/alloy-ppc-test.cc b/src/alloy/frontend/ppc/test/alloy-ppc-test.cc index ed5f202da..5734cbb73 100644 --- a/src/alloy/frontend/ppc/test/alloy-ppc-test.cc +++ b/src/alloy/frontend/ppc/test/alloy-ppc-test.cc @@ -285,6 +285,24 @@ class TestRunner { auto reg_name = it.second.substr(0, space_pos); auto reg_value = it.second.substr(space_pos + 1); ppc_state->SetRegFromString(reg_name.c_str(), reg_value.c_str()); + } else if (it.first == "MEMORY_IN") { + size_t space_pos = it.second.find(" "); + auto address_str = it.second.substr(0, space_pos); + auto bytes_str = it.second.substr(space_pos + 1); + uint32_t address = std::strtoul(address_str.c_str(), nullptr, 16); + auto p = memory->Translate(address); + const char* c = bytes_str.c_str(); + while (*c) { + while (*c == ' ') ++c; + if (!*c) { + break; + } + char ccs[3] = { c[0], c[1], 0 }; + c += 2; + uint32_t b = std::strtoul(ccs, nullptr, 16); + *p = static_cast(b); + ++p; + } } } return true; @@ -390,11 +408,10 @@ bool RunTests(const std::wstring& test_name) { std::vector test_suites; bool load_failed = false; for (auto& test_path : test_files) { - if (!test_name.empty() && test_path != test_name) { + TestSuite test_suite(test_path); + if (!test_name.empty() && test_suite.name != test_name) { continue; } - - TestSuite test_suite(test_path); if (!test_suite.Load()) { PLOGE("TEST SUITE %ls FAILED TO LOAD", test_path.c_str()); load_failed = true; diff --git a/src/alloy/vec128.h b/src/alloy/vec128.h index 8a4a9a039..f756f805e 100644 --- a/src/alloy/vec128.h +++ b/src/alloy/vec128.h @@ -104,6 +104,9 @@ typedef struct alignas(16) vec128_s { bool operator==(const vec128_s& b) const { return low == b.low && high == b.high; } + bool operator!=(const vec128_s& b) const { + return low != b.low || high != b.high; + } } vec128_t; static inline vec128_t vec128i(uint32_t src) {