diff --git a/Scripts/json_config_parse.py b/Scripts/json_config_parse.py index 5c523e8ff..e3bc79558 100644 --- a/Scripts/json_config_parse.py +++ b/Scripts/json_config_parse.py @@ -62,6 +62,10 @@ class Mode(Flag) : MODE_32 = 0 MODE_64 = 1 +class HostFeatures(Flag) : + ANY = 0 + AVX_ONLY = 1 + RegStringLookup = { "NONE": Regs.REG_NONE, "RAX": Regs.REG_RAX, @@ -123,6 +127,11 @@ ModeStringLookup = { "64BIT": Mode.MODE_64, } +HostFeaturesLookup = { + "ANY" : HostFeatures.ANY, + "AVX" : HostFeatures.AVX_ONLY, +} + def parse_hexstring(s): length = 0 byte_data = [] @@ -143,6 +152,7 @@ def parse_json(json_text, output_file): OptionIgnore = Regs.REG_NONE OptionABI = ABI.ABI_SYSTEMV OptionMode = Mode.MODE_64 + OptionHostFeatures = HostFeatures.ANY OptionStackSize = 4096 OptionEntryPoint = 1 OptionRegData = {} @@ -196,6 +206,13 @@ def parse_json(json_text, output_file): sys.exit("Invalid Mode") OptionMode = ModeStringLookup[data] + if ("HOSTFEATURES" in json_object): + data = json_object["HOSTFEATURES"] + data = data.upper() + if not (data in HostFeaturesLookup): + sys.exit("Invalid host feature") + OptionHostFeatures = HostFeaturesLookup[data] + if ("STACKSIZE" in json_object): data = json_object["STACKSIZE"] OptionStackSize = int(data, 0) @@ -294,9 +311,10 @@ def parse_json(json_text, output_file): config_file.write(struct.pack('Q', OptionEntryPoint)) config_file.write(struct.pack('I', OptionABI.value)) config_file.write(struct.pack('I', OptionMode.value)) + config_file.write(struct.pack('I', OptionHostFeatures.value)) # Total length of header, including offsets/counts below - headerLength = (8 * 4) + (4 * 2) + (4 * 8) + headerLength = (8 * 4) + (4 * 3) + (4 * 8) offset = headerLength # memory regions offset/count diff --git a/Source/Tests/HarnessHelpers.h b/Source/Tests/HarnessHelpers.h index 6c2f2c21a..def9b9ef0 100644 --- a/Source/Tests/HarnessHelpers.h +++ b/Source/Tests/HarnessHelpers.h @@ -364,6 +364,7 @@ namespace FEX::HarnessHelper { } bool Is64BitMode() const { return BaseConfig.OptionMode == 1; } + bool RequiresAVX() const { return BaseConfig.OptionHostFeatures == 1; } private: FEX_CONFIG_OPT(ConfigDumpGPRs, DUMPGPRS); @@ -375,6 +376,7 @@ namespace FEX::HarnessHelper { uint64_t OptionEntryPoint; uint32_t OptionABI; uint32_t OptionMode; + uint32_t OptionHostFeatures; uint32_t OptionMemoryRegionOffset; uint32_t OptionMemoryRegionCount; uint32_t OptionRegDataOffset; @@ -494,6 +496,7 @@ namespace FEX::HarnessHelper { } bool Is64BitMode() const { return Config.Is64BitMode(); } + bool RequiresAVX() const { return Config.RequiresAVX(); } private: constexpr static uint64_t STACK_SIZE = FHU::FEX_PAGE_SIZE; diff --git a/Source/Tests/IRLoader.cpp b/Source/Tests/IRLoader.cpp index eaa05108a..a060b3856 100644 --- a/Source/Tests/IRLoader.cpp +++ b/Source/Tests/IRLoader.cpp @@ -131,6 +131,10 @@ public: return EntryRIP; } + bool RequiresAVX() const { + return Config.RequiresAVX(); + } + private: uint64_t EntryRIP{}; std::unique_ptr ParsedCode; @@ -185,7 +189,14 @@ int main(int argc, char **argv, char **const envp) FEXCore::Context::SetSyscallHandler(CTX, new DummySyscallHandler()); IRCodeLoader Loader(Args[0], Args[1]); - + + // Skip tests that require AVX on hosts that don't support it. + const bool SupportsAVX = FEXCore::Context::GetHostFeatures(CTX).SupportsAVX; + if (!SupportsAVX && Loader.RequiresAVX()) { + FEXCore::Context::DestroyContext(CTX); + return 0; + } + int Return{}; if (Loader.LoadIR(CTX)) @@ -225,7 +236,6 @@ int main(int argc, char **argv, char **const envp) FEXCore::Core::CPUState State; FEXCore::Context::GetCPUState(CTX, &State); - const bool SupportsAVX = FEXCore::Context::GetHostFeatures(CTX).SupportsAVX; const bool Passed = Loader.CompareStates(&State, SupportsAVX); LogMan::Msg::IFmt("Passed? {}\n", Passed ? "Yes" : "No"); diff --git a/unittests/IR/Correctness/FPRStoreTruncate.ir b/unittests/IR/Correctness/FPRStoreTruncate.ir index ead794844..80f138603 100644 --- a/unittests/IR/Correctness/FPRStoreTruncate.ir +++ b/unittests/IR/Correctness/FPRStoreTruncate.ir @@ -6,6 +6,7 @@ ; "XMM6": ["0x0000000000002120","0x0000000000000000"], ; "XMM7": ["0x0000000000000020","0x0000000000000000"] ; }, +; "HostFeatures": "AVX", ; "MemoryRegions": { ; "0x1000000": "4096" ; },