Commit 059cc8ac by H.J. Lu Committed by H.J. Lu

i386: Enable AVX/AVX512 features only if supported by OSXSAVE

Enable AVX and AVX512 features only if their states are supported by
OSXSAVE.

	PR target/85100
	* config/i386/cpuinfo.c (XCR_XFEATURE_ENABLED_MASK): New.
	(XSTATE_FP): Likewise.
	(XSTATE_SSE): Likewise.
	(XSTATE_YMM): Likewise.
	(XSTATE_OPMASK): Likewise.
	(XSTATE_ZMM): Likewise.
	(XSTATE_HI_ZMM): Likewise.
	(XCR_AVX_ENABLED_MASK): Likewise.
	(XCR_AVX512F_ENABLED_MASK): Likewise.
	(get_available_features): Enable AVX and AVX512 features only
	if their states are supported by OSXSAVE.

From-SVN: r258954
parent c7cb6c17
2018-03-29 H.J. Lu <hongjiu.lu@intel.com>
PR target/85100
* config/i386/cpuinfo.c (XCR_XFEATURE_ENABLED_MASK): New.
(XSTATE_FP): Likewise.
(XSTATE_SSE): Likewise.
(XSTATE_YMM): Likewise.
(XSTATE_OPMASK): Likewise.
(XSTATE_ZMM): Likewise.
(XSTATE_HI_ZMM): Likewise.
(XCR_AVX_ENABLED_MASK): Likewise.
(XCR_AVX512F_ENABLED_MASK): Likewise.
(get_available_features): Enable AVX and AVX512 features only
if their states are supported by OSXSAVE.
2018-03-22 Igor Tsimbalist <igor.v.tsimbalist@intel.com> 2018-03-22 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
PR target/85025 PR target/85025
......
...@@ -240,6 +240,40 @@ get_available_features (unsigned int ecx, unsigned int edx, ...@@ -240,6 +240,40 @@ get_available_features (unsigned int ecx, unsigned int edx,
unsigned int features = 0; unsigned int features = 0;
unsigned int features2 = 0; unsigned int features2 = 0;
/* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */
#define XCR_XFEATURE_ENABLED_MASK 0x0
#define XSTATE_FP 0x1
#define XSTATE_SSE 0x2
#define XSTATE_YMM 0x4
#define XSTATE_OPMASK 0x20
#define XSTATE_ZMM 0x40
#define XSTATE_HI_ZMM 0x80
#define XCR_AVX_ENABLED_MASK \
(XSTATE_SSE | XSTATE_YMM)
#define XCR_AVX512F_ENABLED_MASK \
(XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM)
/* Check if AVX and AVX512 are usable. */
int avx_usable = 0;
int avx512_usable = 0;
if ((ecx & bit_OSXSAVE))
{
/* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and
ZMM16-ZMM31 states are supported by OSXSAVE. */
unsigned int xcrlow;
unsigned int xcrhigh;
asm (".byte 0x0f, 0x01, 0xd0"
: "=a" (xcrlow), "=d" (xcrhigh)
: "c" (XCR_XFEATURE_ENABLED_MASK));
if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK)
{
avx_usable = 1;
avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK)
== XCR_AVX512F_ENABLED_MASK);
}
}
#define set_feature(f) \ #define set_feature(f) \
if (f < 32) features |= (1U << f); else features2 |= (1U << (f - 32)) if (f < 32) features |= (1U << f); else features2 |= (1U << (f - 32))
...@@ -265,10 +299,13 @@ get_available_features (unsigned int ecx, unsigned int edx, ...@@ -265,10 +299,13 @@ get_available_features (unsigned int ecx, unsigned int edx,
set_feature (FEATURE_SSE4_1); set_feature (FEATURE_SSE4_1);
if (ecx & bit_SSE4_2) if (ecx & bit_SSE4_2)
set_feature (FEATURE_SSE4_2); set_feature (FEATURE_SSE4_2);
if (ecx & bit_AVX) if (avx_usable)
set_feature (FEATURE_AVX); {
if (ecx & bit_FMA) if (ecx & bit_AVX)
set_feature (FEATURE_FMA); set_feature (FEATURE_AVX);
if (ecx & bit_FMA)
set_feature (FEATURE_FMA);
}
/* Get Advanced Features at level 7 (eax = 7, ecx = 0). */ /* Get Advanced Features at level 7 (eax = 7, ecx = 0). */
if (max_cpuid_level >= 7) if (max_cpuid_level >= 7)
...@@ -276,44 +313,50 @@ get_available_features (unsigned int ecx, unsigned int edx, ...@@ -276,44 +313,50 @@ get_available_features (unsigned int ecx, unsigned int edx,
__cpuid_count (7, 0, eax, ebx, ecx, edx); __cpuid_count (7, 0, eax, ebx, ecx, edx);
if (ebx & bit_BMI) if (ebx & bit_BMI)
set_feature (FEATURE_BMI); set_feature (FEATURE_BMI);
if (ebx & bit_AVX2) if (avx_usable)
set_feature (FEATURE_AVX2); {
if (ebx & bit_AVX2)
set_feature (FEATURE_AVX2);
}
if (ebx & bit_BMI2) if (ebx & bit_BMI2)
set_feature (FEATURE_BMI2); set_feature (FEATURE_BMI2);
if (ebx & bit_AVX512F) if (avx512_usable)
set_feature (FEATURE_AVX512F); {
if (ebx & bit_AVX512VL) if (ebx & bit_AVX512F)
set_feature (FEATURE_AVX512VL); set_feature (FEATURE_AVX512F);
if (ebx & bit_AVX512BW) if (ebx & bit_AVX512VL)
set_feature (FEATURE_AVX512BW); set_feature (FEATURE_AVX512VL);
if (ebx & bit_AVX512DQ) if (ebx & bit_AVX512BW)
set_feature (FEATURE_AVX512DQ); set_feature (FEATURE_AVX512BW);
if (ebx & bit_AVX512CD) if (ebx & bit_AVX512DQ)
set_feature (FEATURE_AVX512CD); set_feature (FEATURE_AVX512DQ);
if (ebx & bit_AVX512PF) if (ebx & bit_AVX512CD)
set_feature (FEATURE_AVX512PF); set_feature (FEATURE_AVX512CD);
if (ebx & bit_AVX512ER) if (ebx & bit_AVX512PF)
set_feature (FEATURE_AVX512ER); set_feature (FEATURE_AVX512PF);
if (ebx & bit_AVX512IFMA) if (ebx & bit_AVX512ER)
set_feature (FEATURE_AVX512IFMA); set_feature (FEATURE_AVX512ER);
if (ecx & bit_AVX512VBMI) if (ebx & bit_AVX512IFMA)
set_feature (FEATURE_AVX512VBMI); set_feature (FEATURE_AVX512IFMA);
if (ecx & bit_AVX512VBMI2) if (ecx & bit_AVX512VBMI)
set_feature (FEATURE_AVX512VBMI2); set_feature (FEATURE_AVX512VBMI);
if (ecx & bit_GFNI) if (ecx & bit_AVX512VBMI2)
set_feature (FEATURE_GFNI); set_feature (FEATURE_AVX512VBMI2);
if (ecx & bit_VPCLMULQDQ) if (ecx & bit_GFNI)
set_feature (FEATURE_VPCLMULQDQ); set_feature (FEATURE_GFNI);
if (ecx & bit_AVX512VNNI) if (ecx & bit_VPCLMULQDQ)
set_feature (FEATURE_AVX512VNNI); set_feature (FEATURE_VPCLMULQDQ);
if (ecx & bit_AVX512BITALG) if (ecx & bit_AVX512VNNI)
set_feature (FEATURE_AVX512BITALG); set_feature (FEATURE_AVX512VNNI);
if (ecx & bit_AVX512VPOPCNTDQ) if (ecx & bit_AVX512BITALG)
set_feature (FEATURE_AVX512VPOPCNTDQ); set_feature (FEATURE_AVX512BITALG);
if (edx & bit_AVX5124VNNIW) if (ecx & bit_AVX512VPOPCNTDQ)
set_feature (FEATURE_AVX5124VNNIW); set_feature (FEATURE_AVX512VPOPCNTDQ);
if (edx & bit_AVX5124FMAPS) if (edx & bit_AVX5124VNNIW)
set_feature (FEATURE_AVX5124FMAPS); set_feature (FEATURE_AVX5124VNNIW);
if (edx & bit_AVX5124FMAPS)
set_feature (FEATURE_AVX5124FMAPS);
}
} }
/* Check cpuid level of extended features. */ /* Check cpuid level of extended features. */
...@@ -325,10 +368,13 @@ get_available_features (unsigned int ecx, unsigned int edx, ...@@ -325,10 +368,13 @@ get_available_features (unsigned int ecx, unsigned int edx,
if (ecx & bit_SSE4a) if (ecx & bit_SSE4a)
set_feature (FEATURE_SSE4_A); set_feature (FEATURE_SSE4_A);
if (ecx & bit_FMA4) if (avx_usable)
set_feature (FEATURE_FMA4); {
if (ecx & bit_XOP) if (ecx & bit_FMA4)
set_feature (FEATURE_XOP); set_feature (FEATURE_FMA4);
if (ecx & bit_XOP)
set_feature (FEATURE_XOP);
}
} }
__cpu_model.__cpu_features[0] = features; __cpu_model.__cpu_features[0] = features;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment