[x64] Add host-extension detection preprocessor

Rather than having a huge list of if-statements that all do the same
thing, this preprocessor allows a more concise pattern to detecting if
the emit-flag is enabled as well as the correlated Xbyak flag that it
needs to check for to before allowing the feature-flag to be emitted.

Also moved the AVX-check to the beginning to early-out rather than do a
bunch of wasted work only to find out last that the host doesn't even
support AVX.
This commit is contained in:
Wunkolo 2022-01-14 10:33:23 -08:00 committed by Rick Gibbed
parent e4ae1d8b2f
commit f7c14a089d
1 changed files with 19 additions and 29 deletions

View File

@ -74,41 +74,31 @@ X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator)
backend_(backend),
code_cache_(backend->code_cache()),
allocator_(allocator) {
if (cvars::x64_extension_mask & kX64EmitAVX2)
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tAVX2) ? kX64EmitAVX2 : 0;
if (cvars::x64_extension_mask & kX64EmitFMA)
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tFMA) ? kX64EmitFMA : 0;
if (cvars::x64_extension_mask & kX64EmitLZCNT)
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tLZCNT) ? kX64EmitLZCNT : 0;
if (cvars::x64_extension_mask & kX64EmitBMI1)
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tBMI1) ? kX64EmitBMI1 : 0;
if (cvars::x64_extension_mask & kX64EmitBMI2)
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tBMI2) ? kX64EmitBMI2 : 0;
if (cvars::x64_extension_mask & kX64EmitF16C)
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tF16C) ? kX64EmitF16C : 0;
if (cvars::x64_extension_mask & kX64EmitMovbe)
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tMOVBE) ? kX64EmitMovbe : 0;
if (cvars::x64_extension_mask & kX64EmitGFNI)
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tGFNI) ? kX64EmitGFNI : 0;
if (cvars::x64_extension_mask & kX64EmitAVX512F)
feature_flags_ |=
cpu_.has(Xbyak::util::Cpu::tAVX512F) ? kX64EmitAVX512F : 0;
if (cvars::x64_extension_mask & kX64EmitAVX512VL)
feature_flags_ |=
cpu_.has(Xbyak::util::Cpu::tAVX512VL) ? kX64EmitAVX512VL : 0;
if (cvars::x64_extension_mask & kX64EmitAVX512BW)
feature_flags_ |=
cpu_.has(Xbyak::util::Cpu::tAVX512BW) ? kX64EmitAVX512BW : 0;
if (cvars::x64_extension_mask & kX64EmitAVX512DQ)
feature_flags_ |=
cpu_.has(Xbyak::util::Cpu::tAVX512DQ) ? kX64EmitAVX512DQ : 0;
if (!cpu_.has(Xbyak::util::Cpu::tAVX)) {
xe::FatalError(
"Your CPU does not support AVX, which is required by Xenia. See the "
"FAQ for system requirements at https://xenia.jp");
return;
}
#define TEST_EMIT_FEATURE(emit, ext) \
if ((cvars::x64_extension_mask & emit) == emit) { \
feature_flags_ |= (cpu_.has(ext) ? emit : 0); \
}
TEST_EMIT_FEATURE(kX64EmitAVX2, Xbyak::util::Cpu::tAVX2);
TEST_EMIT_FEATURE(kX64EmitFMA, Xbyak::util::Cpu::tFMA);
TEST_EMIT_FEATURE(kX64EmitLZCNT, Xbyak::util::Cpu::tLZCNT);
TEST_EMIT_FEATURE(kX64EmitBMI1, Xbyak::util::Cpu::tBMI1);
TEST_EMIT_FEATURE(kX64EmitF16C, Xbyak::util::Cpu::tF16C);
TEST_EMIT_FEATURE(kX64EmitMovbe, Xbyak::util::Cpu::tMOVBE);
TEST_EMIT_FEATURE(kX64EmitGFNI, Xbyak::util::Cpu::tGFNI);
TEST_EMIT_FEATURE(kX64EmitAVX512F, Xbyak::util::Cpu::tAVX512F);
TEST_EMIT_FEATURE(kX64EmitAVX512VL, Xbyak::util::Cpu::tAVX512VL);
TEST_EMIT_FEATURE(kX64EmitAVX512BW, Xbyak::util::Cpu::tAVX512BW);
TEST_EMIT_FEATURE(kX64EmitAVX512DQ, Xbyak::util::Cpu::tAVX512DQ);
#undef TEST_EMIT_FEATURE
}
X64Emitter::~X64Emitter() = default;