Merge pull request #3152 from Sonicadvance1/instcountci_x87_f64

InstCountCI: Support f64 reduced precision mode tests
This commit is contained in:
Ryan Houdek authored and GitHub committed 2023-09-24 19:29:37 -07:00
commit 5eed24a242
3 files changed
+11802 -5

No files matched your search

+20
View File
@@ -73,6 +73,7 @@ def parse_json_data(json_filename, json_data, output_binary_path):
Bitness = 64
EnabledHostFeatures = HostFeatures.FEATURE_ANY
DisabledHostFeatures = HostFeatures.FEATURE_ANY
OptionEnvironmentVariables = {}
if "Features" in json_data:
items = json_data["Features"]
@@ -85,6 +86,14 @@ def parse_json_data(json_filename, json_data, output_binary_path):
if ("DisabledHostFeatures" in items):
DisabledHostFeatures = GetHostFeatures(items["DisabledHostFeatures"])
if ("Env" in items):
data = items["Env"]
if not (type(data) is dict):
sys.exit("Environment variables value must be list of key:value pairs")
for data_key, data_val in data.items():
OptionEnvironmentVariables[data_key] = data_val
for key, items in json_data["Instructions"].items():
ExpectedInstructionCount = 0
Optimal = 0
@@ -140,6 +149,8 @@ def parse_json_data(json_filename, json_data, output_binary_path):
# uint64_t NumTests;
# uint64_t EnabledHostFeatures;
# uint64_t DisabledHostFeatures;
# uint64_t EnvironmentVariableCount;
# char env[];
# TestInfo Tests[NumTests];
# };
# struct TestInfo {
@@ -152,11 +163,20 @@ def parse_json_data(json_filename, json_data, output_binary_path):
# };
MemData = bytes()
# Add the header
MemData += struct.pack('Q', Bitness)
MemData += struct.pack('Q', len(TestDataMap))
MemData += struct.pack('Q', EnabledHostFeatures.value)
MemData += struct.pack('Q', DisabledHostFeatures.value)
MemData += struct.pack('Q', len(OptionEnvironmentVariables.items()))
# Write environment variables
for key, val in OptionEnvironmentVariables.items():
MemData += key.encode()
MemData += struct.pack('B', 0)
MemData += val.encode()
MemData += struct.pack('B', 0)
# Add each test
for key, item in TestDataMap.items():
+76 -5
View File
@@ -239,17 +239,20 @@ struct TestHeader {
uint64_t NumTests{};
uint64_t EnabledHostFeatures;
uint64_t DisabledHostFeatures;
TestInfo Tests[];
uint64_t EnvironmentVariableCount;
uint8_t Data[];
};
static fextl::vector<char> TestData;
static TestHeader const *TestHeaderData{};
static TestInfo const *TestsStart{};
static fextl::vector<std::pair<std::string_view, std::string_view>> EnvironmentVariables{};
static bool TestInstructions(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread, const char *UpdatedInstructionCountsPath) {
LogMan::Msg::IFmt("Compiling code");
// Tell FEXCore to compile all the instructions upfront.
TestInfo const *CurrentTest = &TestHeaderData->Tests[0];
TestInfo const *CurrentTest = TestsStart;
for (size_t i = 0; i < TestHeaderData->NumTests; ++i) {
uint64_t CodeRIP = (uint64_t)&CurrentTest->Code[0];
LogMan::Msg::IFmt("Compiling instruction '{}'", CurrentTest->TestInst);
@@ -264,7 +267,7 @@ static bool TestInstructions(FEXCore::Context::Context *CTX, FEXCore::Core::Inte
bool TestsPassed {true};
// Get all the data for the instructions compiled.
CurrentTest = &TestHeaderData->Tests[0];
CurrentTest = TestsStart;
for (size_t i = 0; i < TestHeaderData->NumTests; ++i) {
uint64_t CodeRIP = (uint64_t)CurrentTest->Code;
// Get the instruction stats.
@@ -308,7 +311,7 @@ static bool TestInstructions(FEXCore::Context::Context *CTX, FEXCore::Core::Inte
FD.Write("{\n", 2);
CurrentTest = &TestHeaderData->Tests[0];
CurrentTest = TestsStart;
for (size_t i = 0; i < TestHeaderData->NumTests; ++i) {
uint64_t CodeRIP = (uint64_t)CurrentTest->Code;
// Get the instruction stats.
@@ -348,16 +351,81 @@ bool LoadTests(const char *Path) {
}
TestHeaderData = reinterpret_cast<TestHeader const*>(TestData.data());
// Need to walk past the environment variables to get to the actual tests.
const uint8_t *Data = TestHeaderData->Data;
for (size_t i = 0; i < TestHeaderData->EnvironmentVariableCount; ++i) {
// Environment variables are a pair of null terminated strings.
Data += strlen(reinterpret_cast<const char*>(Data)) + 1;
Data += strlen(reinterpret_cast<const char*>(Data)) + 1;
}
TestsStart = reinterpret_cast<const TestInfo*>(Data);
return true;
}
namespace {
static const fextl::vector<std::pair<const char*, FEXCore::Config::ConfigOption>> EnvConfigLookup = {{
#define OPT_BASE(type, group, enum, json, default) {"FEX_" #enum, FEXCore::Config::ConfigOption::CONFIG_##enum},
#include <FEXCore/Config/ConfigValues.inl>
}};
// Claims to be a local application config layer
class TestEnvLoader final : public FEXCore::Config::Layer {
public:
explicit TestEnvLoader()
: FEXCore::Config::Layer(FEXCore::Config::LayerType::LAYER_LOCAL_APP) {
Load();
}
void Load() override {
fextl::unordered_map<std::string_view, std::string> EnvMap;
const uint8_t *Data = TestHeaderData->Data;
for (size_t i = 0; i < TestHeaderData->EnvironmentVariableCount; ++i) {
// Environment variables are a pair of null terminated strings.
const std::string_view Key = reinterpret_cast<const char*>(Data);
Data += strlen(reinterpret_cast<const char*>(Data)) + 1;
const std::string_view Value_View = reinterpret_cast<const char*>(Data);
Data += strlen(reinterpret_cast<const char*>(Data)) + 1;
std::optional<fextl::string> Value;
#define ENVLOADER
#include <FEXCore/Config/ConfigOptions.inl>
if (Value) {
EnvMap.insert_or_assign(Key, *Value);
}
else {
EnvMap.insert_or_assign(Key, Value_View);
}
}
auto GetVar = [&](const std::string_view id) -> std::optional<std::string_view> {
const auto it = EnvMap.find(id);
if (it == EnvMap.end())
return std::nullopt;
return it->second;
};
for (auto &it : EnvConfigLookup) {
if (auto Value = GetVar(it.first); Value) {
Set(it.second, *Value);
}
}
}
private:
fextl::vector<std::pair<std::string_view, std::string_view>> Env;
};
}
int main(int argc, char **argv, char **const envp) {
FEXCore::Allocator::GLIBCScopedFault GLIBFaultScope;
LogMan::Throw::InstallHandler(AssertHandler);
LogMan::Msg::InstallHandler(MsgHandler);
FEXCore::Config::Initialize();
FEXCore::Config::Load();
FEXCore::Config::ReloadMetaLayer();
if (argc < 2) {
LogMan::Msg::EFmt("Usage: {} <Test binary> [Changed instruction count.json]", argv[0]);
@@ -369,6 +437,9 @@ int main(int argc, char **argv, char **const envp) {
return 1;
}
FEXCore::Config::AddLayer(fextl::make_unique<TestEnvLoader>());
FEXCore::Config::ReloadMetaLayer();
// Setup configurations that this tool needs
// Maximum one instruction.
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_MAXINST, "1");
File diff suppressed because it is too large. Load diff