From 41fb11d84604526983a6656a89868608dcc1e6c9 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Fri, 31 Mar 2017 22:14:29 +0200 Subject: [PATCH] gsdx: cpu detection take 3! Don't use 64 bits type in Xbyak::Cpu Recent GCC uses SSE4/AVX code to optimize the 64 bits operation. It is bad idea as it would generate an illegal instruction on older CPU. --- plugins/GSdx/xbyak/xbyak_util.h | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/plugins/GSdx/xbyak/xbyak_util.h b/plugins/GSdx/xbyak/xbyak_util.h index 11f510c4f7..346cc8164b 100644 --- a/plugins/GSdx/xbyak/xbyak_util.h +++ b/plugins/GSdx/xbyak/xbyak_util.h @@ -82,11 +82,28 @@ extern "C" unsigned __int64 __xgetbv(int); namespace Xbyak { namespace util { +/* GCC uses AVX/SSE4 operation to handle the uint64 type. + * + * It is quite annoying because the purpose of the code is to test the support + * of AVX/SSEn + * + * So far, we don't need other ISA on i386 so I hacked the code to limit the + * type to 32 bits. If we want to support AVX512 we might need to shuffle the + * code a bit. + * + * Extra note: it would be waste to use AVX512 on 32 bits, registers are + * limited to 8 instead of 32. + */ + /** CPU detection class */ class Cpu { +#ifdef XBYAK64 uint64 type_; +#else + uint32 type_; +#endif unsigned int get32bitAsBE(const char *x) const { return x[0] | (x[1] << 8) | (x[2] << 16) | (x[3] << 24); @@ -155,7 +172,11 @@ public: return ((uint64)edx << 32) | eax; #endif } +#ifdef XBYAK64 typedef uint64 Type; +#else + typedef uint32 Type; +#endif static const Type NONE = 0; static const Type tMMX = 1 << 0; static const Type tMMX2 = 1 << 1; @@ -191,6 +212,7 @@ public: static const Type tADX = 1 << 28; // adcx, adox static const Type tRDSEED = 1 << 29; // rdseed static const Type tSMAP = 1 << 30; // stac +#ifdef XBYAK64 static const Type tHLE = uint64(1) << 31; // xacquire, xrelease, xtest static const Type tRTM = uint64(1) << 32; // xbegin, xend, xabort static const Type tF16C = uint64(1) << 33; // vcvtph2ps, vcvtps2ph @@ -204,6 +226,7 @@ public: static const Type tAVX512BW = uint64(1) << 41; static const Type tAVX512VL = uint64(1) << 42; static const Type tAVX512VBMI = uint64(1) << 43; +#endif Cpu() : type_(NONE) @@ -233,13 +256,15 @@ public: if (data[2] & (1U << 9)) type_ |= tSSSE3; if (data[2] & (1U << 19)) type_ |= tSSE41; if (data[2] & (1U << 20)) type_ |= tSSE42; +#ifdef XBYAK64 if (data[2] & (1U << 22)) type_ |= tMOVBE; + if (data[2] & (1U << 29)) type_ |= tF16C; +#endif if (data[2] & (1U << 23)) type_ |= tPOPCNT; if (data[2] & (1U << 25)) type_ |= tAESNI; if (data[2] & (1U << 1)) type_ |= tPCLMULQDQ; if (data[2] & (1U << 27)) type_ |= tOSXSAVE; if (data[2] & (1U << 30)) type_ |= tRDRAND; - if (data[2] & (1U << 29)) type_ |= tF16C; if (data[3] & (1U << 15)) type_ |= tCMOV; if (data[3] & (1U << 23)) type_ |= tMMX; @@ -252,6 +277,7 @@ public: if ((bv & 6) == 6) { if (data[2] & (1U << 28)) type_ |= tAVX; if (data[2] & (1U << 12)) type_ |= tFMA; +#ifdef XBYAK64 if (((bv >> 5) & 7) == 7) { getCpuid(7, data); if (data[1] & (1U << 16)) type_ |= tAVX512F; @@ -267,6 +293,7 @@ public: if (data[2] & (1U << 1)) type_ |= tAVX512VBMI; } } +#endif } } if (maxNum >= 7) { @@ -278,8 +305,10 @@ public: if (data[1] & (1U << 18)) type_ |= tRDSEED; if (data[1] & (1U << 19)) type_ |= tADX; if (data[1] & (1U << 20)) type_ |= tSMAP; +#ifdef XBYAK64 if (data[1] & (1U << 4)) type_ |= tHLE; if (data[1] & (1U << 11)) type_ |= tRTM; +#endif } setFamily(); }