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.
This commit is contained in:
Gregory Hainaut 2017-03-31 22:14:29 +02:00
parent bcc0160103
commit 41fb11d846
1 changed files with 30 additions and 1 deletions

View File

@ -82,11 +82,28 @@ extern "C" unsigned __int64 __xgetbv(int);
namespace Xbyak { namespace util { 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 CPU detection class
*/ */
class Cpu { class Cpu {
#ifdef XBYAK64
uint64 type_; uint64 type_;
#else
uint32 type_;
#endif
unsigned int get32bitAsBE(const char *x) const unsigned int get32bitAsBE(const char *x) const
{ {
return x[0] | (x[1] << 8) | (x[2] << 16) | (x[3] << 24); return x[0] | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
@ -155,7 +172,11 @@ public:
return ((uint64)edx << 32) | eax; return ((uint64)edx << 32) | eax;
#endif #endif
} }
#ifdef XBYAK64
typedef uint64 Type; typedef uint64 Type;
#else
typedef uint32 Type;
#endif
static const Type NONE = 0; static const Type NONE = 0;
static const Type tMMX = 1 << 0; static const Type tMMX = 1 << 0;
static const Type tMMX2 = 1 << 1; static const Type tMMX2 = 1 << 1;
@ -191,6 +212,7 @@ public:
static const Type tADX = 1 << 28; // adcx, adox static const Type tADX = 1 << 28; // adcx, adox
static const Type tRDSEED = 1 << 29; // rdseed static const Type tRDSEED = 1 << 29; // rdseed
static const Type tSMAP = 1 << 30; // stac static const Type tSMAP = 1 << 30; // stac
#ifdef XBYAK64
static const Type tHLE = uint64(1) << 31; // xacquire, xrelease, xtest static const Type tHLE = uint64(1) << 31; // xacquire, xrelease, xtest
static const Type tRTM = uint64(1) << 32; // xbegin, xend, xabort static const Type tRTM = uint64(1) << 32; // xbegin, xend, xabort
static const Type tF16C = uint64(1) << 33; // vcvtph2ps, vcvtps2ph static const Type tF16C = uint64(1) << 33; // vcvtph2ps, vcvtps2ph
@ -204,6 +226,7 @@ public:
static const Type tAVX512BW = uint64(1) << 41; static const Type tAVX512BW = uint64(1) << 41;
static const Type tAVX512VL = uint64(1) << 42; static const Type tAVX512VL = uint64(1) << 42;
static const Type tAVX512VBMI = uint64(1) << 43; static const Type tAVX512VBMI = uint64(1) << 43;
#endif
Cpu() Cpu()
: type_(NONE) : type_(NONE)
@ -233,13 +256,15 @@ public:
if (data[2] & (1U << 9)) type_ |= tSSSE3; if (data[2] & (1U << 9)) type_ |= tSSSE3;
if (data[2] & (1U << 19)) type_ |= tSSE41; if (data[2] & (1U << 19)) type_ |= tSSE41;
if (data[2] & (1U << 20)) type_ |= tSSE42; if (data[2] & (1U << 20)) type_ |= tSSE42;
#ifdef XBYAK64
if (data[2] & (1U << 22)) type_ |= tMOVBE; 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 << 23)) type_ |= tPOPCNT;
if (data[2] & (1U << 25)) type_ |= tAESNI; if (data[2] & (1U << 25)) type_ |= tAESNI;
if (data[2] & (1U << 1)) type_ |= tPCLMULQDQ; if (data[2] & (1U << 1)) type_ |= tPCLMULQDQ;
if (data[2] & (1U << 27)) type_ |= tOSXSAVE; if (data[2] & (1U << 27)) type_ |= tOSXSAVE;
if (data[2] & (1U << 30)) type_ |= tRDRAND; 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 << 15)) type_ |= tCMOV;
if (data[3] & (1U << 23)) type_ |= tMMX; if (data[3] & (1U << 23)) type_ |= tMMX;
@ -252,6 +277,7 @@ public:
if ((bv & 6) == 6) { if ((bv & 6) == 6) {
if (data[2] & (1U << 28)) type_ |= tAVX; if (data[2] & (1U << 28)) type_ |= tAVX;
if (data[2] & (1U << 12)) type_ |= tFMA; if (data[2] & (1U << 12)) type_ |= tFMA;
#ifdef XBYAK64
if (((bv >> 5) & 7) == 7) { if (((bv >> 5) & 7) == 7) {
getCpuid(7, data); getCpuid(7, data);
if (data[1] & (1U << 16)) type_ |= tAVX512F; if (data[1] & (1U << 16)) type_ |= tAVX512F;
@ -267,6 +293,7 @@ public:
if (data[2] & (1U << 1)) type_ |= tAVX512VBMI; if (data[2] & (1U << 1)) type_ |= tAVX512VBMI;
} }
} }
#endif
} }
} }
if (maxNum >= 7) { if (maxNum >= 7) {
@ -278,8 +305,10 @@ public:
if (data[1] & (1U << 18)) type_ |= tRDSEED; if (data[1] & (1U << 18)) type_ |= tRDSEED;
if (data[1] & (1U << 19)) type_ |= tADX; if (data[1] & (1U << 19)) type_ |= tADX;
if (data[1] & (1U << 20)) type_ |= tSMAP; if (data[1] & (1U << 20)) type_ |= tSMAP;
#ifdef XBYAK64
if (data[1] & (1U << 4)) type_ |= tHLE; if (data[1] & (1U << 4)) type_ |= tHLE;
if (data[1] & (1U << 11)) type_ |= tRTM; if (data[1] & (1U << 11)) type_ |= tRTM;
#endif
} }
setFamily(); setFamily();
} }