/* Check if CPUID is supported by attempting to toggle the ID bit in
* the EFLAGS register. */
get_eflags(a);
set_eflags(a ^ 0x200000);
get_eflags(c);
return a != c;
} #endif
/* Function to test if multimedia instructions are supported... */ int ff_get_cpu_flags_x86(void)
{ int rval = 0;
#ifdef cpuid
int eax, ebx, ecx, edx; int max_std_level, max_ext_level, std_caps = 0, ext_caps = 0; int family = 0, model = 0; union { int i[3]; char c[12]; } vendor; int xcr0_lo = 0, xcr0_hi = 0;
if (!cpuid_test()) return0; /* CPUID not supported */
if (max_std_level >= 1) {
cpuid(1, eax, ebx, ecx, std_caps);
family = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
model = ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0); if (std_caps & (1 << 15))
rval |= AV_CPU_FLAG_CMOV; if (std_caps & (1 << 23))
rval |= AV_CPU_FLAG_MMX; if (std_caps & (1 << 25))
rval |= AV_CPU_FLAG_MMXEXT; #if HAVE_SSE if (std_caps & (1 << 25))
rval |= AV_CPU_FLAG_SSE; if (std_caps & (1 << 26))
rval |= AV_CPU_FLAG_SSE2; if (ecx & 1)
rval |= AV_CPU_FLAG_SSE3; if (ecx & 0x2)
rval |= AV_CPU_FLAG_CLMUL; if (ecx & 0x00000200 )
rval |= AV_CPU_FLAG_SSSE3; if (ecx & 0x00080000 )
rval |= AV_CPU_FLAG_SSE4; if (ecx & 0x00100000 )
rval |= AV_CPU_FLAG_SSE42; if (ecx & 0x02000000 )
rval |= AV_CPU_FLAG_AESNI; #if HAVE_AVX /* Check OXSAVE and AVX bits */ if ((ecx & 0x18000000) == 0x18000000) { /* Check for OS support */
xgetbv(0, xcr0_lo, xcr0_hi); if ((xcr0_lo & 0x6) == 0x6) {
rval |= AV_CPU_FLAG_AVX; if (ecx & 0x00001000)
rval |= AV_CPU_FLAG_FMA3;
}
} #endif/* HAVE_AVX */ #endif/* HAVE_SSE */
} if (max_std_level >= 7) {
cpuid(7, eax, ebx, ecx, edx); #if HAVE_AVX2 if ((rval & AV_CPU_FLAG_AVX) && (ebx & 0x00000020))
rval |= AV_CPU_FLAG_AVX2; #if HAVE_AVX512 /* F, CD, BW, DQ, VL */ if ((xcr0_lo & 0xe0) == 0xe0) { /* OPMASK/ZMM state */ if ((rval & AV_CPU_FLAG_AVX2) && (ebx & 0xd0030000) == 0xd0030000) {
rval |= AV_CPU_FLAG_AVX512; #if HAVE_AVX512ICL if ((ebx & 0xd0200000) == 0xd0200000 && (ecx & 0x5f42) == 0x5f42)
rval |= AV_CPU_FLAG_AVX512ICL; #endif/* HAVE_AVX512ICL */
}
} #endif/* HAVE_AVX512 */ #endif/* HAVE_AVX2 */ /* BMI1/2 don't need OS support */ if (ebx & 0x00000008) {
rval |= AV_CPU_FLAG_BMI1; if (ebx & 0x00000100)
rval |= AV_CPU_FLAG_BMI2;
}
}
cpuid(0x80000000, max_ext_level, ebx, ecx, edx);
if (max_ext_level >= 0x80000001) {
cpuid(0x80000001, eax, ebx, ecx, ext_caps); if (ext_caps & (1U << 31))
rval |= AV_CPU_FLAG_3DNOW; if (ext_caps & (1 << 30))
rval |= AV_CPU_FLAG_3DNOWEXT; if (ext_caps & (1 << 23))
rval |= AV_CPU_FLAG_MMX; if (ext_caps & (1 << 22))
rval |= AV_CPU_FLAG_MMXEXT;
if (!strncmp(vendor.c, "AuthenticAMD", 12)) { /* Allow for selectively disabling SSE2 functions on AMD processors withSSE2supportbutnotSSE4a.ThisincludesAthlon64,some Opteron,andsomeSempronprocessors.MMX,SSE,or3DNow!arefaster thanSSE2oftenenoughtoutilizethisspecial-caseflag. AV_CPU_FLAG_SSE2andAV_CPU_FLAG_SSE2SLOWarebothsetinthiscase sothatSSE2isusedunlessexplicitlydisabledbychecking
AV_CPU_FLAG_SSE2SLOW. */ if (rval & AV_CPU_FLAG_SSE2 && !(ecx & 0x00000040))
rval |= AV_CPU_FLAG_SSE2SLOW;
/* Similar to the above but for AVX functions on AMD processors. ThisisnecessaryonlyforfunctionsusingYMMregistersonBulldozer andJaguarbasedCPUsastheylack256-bitexecutionunits.SSE/AVX functionsusingXMMregistersarealwaysfasteronthem. AV_CPU_FLAG_AVXandAV_CPU_FLAG_AVXSLOWarebothsetsothatAVXis
used unless explicitly disabled by checking AV_CPU_FLAG_AVXSLOW. */ if ((family == 0x15 || family == 0x16) && (rval & AV_CPU_FLAG_AVX))
rval |= AV_CPU_FLAG_AVXSLOW;
/* Zen 3 and earlier have slow gather */ if ((family <= 0x19) && (rval & AV_CPU_FLAG_AVX2))
rval |= AV_CPU_FLAG_SLOW_GATHER;
}
/* XOP and FMA4 use the AVX instruction coding scheme, so they can't be
* used unless the OS has AVX support. */ if (rval & AV_CPU_FLAG_AVX) { if (ecx & 0x00000800)
rval |= AV_CPU_FLAG_XOP; if (ecx & 0x00010000)
rval |= AV_CPU_FLAG_FMA4;
}
}
if (!strncmp(vendor.c, "GenuineIntel", 12)) { if (family == 6 && (model == 9 || model == 13 || model == 14)) { /* 6/9 (pentium-m "banias"), 6/13 (pentium-m "dothan"), and *6/14(core1"yonah")theoreticallysupportsse2,butit's *usuallyslowerthanmmx,solet'sjustpretendtheydon't. *AV_CPU_FLAG_SSE2isdisabledandAV_CPU_FLAG_SSE2SLOWis *enabledsothatSSE2isnotusedunlessexplicitlyenabled *bycheckingAV_CPU_FLAG_SSE2SLOW.Thesamesituation
* applies for AV_CPU_FLAG_SSE3 and AV_CPU_FLAG_SSE3SLOW. */ if (rval & AV_CPU_FLAG_SSE2)
rval ^= AV_CPU_FLAG_SSE2SLOW | AV_CPU_FLAG_SSE2; if (rval & AV_CPU_FLAG_SSE3)
rval ^= AV_CPU_FLAG_SSE3SLOW | AV_CPU_FLAG_SSE3;
} /* The Atom processor has SSSE3 support, which is useful in many cases, *butsometimestheSSSE3versionisslowerthantheSSE2equivalent *ontheAtom,butisgenerallyfasteronotherprocessorssupporting *SSSE3.ThisflagallowsforselectivelydisablingcertainSSSE3
* functions on the Atom. */ if (family == 6 && model == 28)
rval |= AV_CPU_FLAG_ATOM;
/* Conroe has a slow shuffle unit. Check the model number to ensure not
* to include crippled low-end Penryns and Nehalems that lack SSE4. */ if ((rval & AV_CPU_FLAG_SSSE3) && !(rval & AV_CPU_FLAG_SSE4) &&
family == 6 && model < 23)
rval |= AV_CPU_FLAG_SSSE3SLOW;
/* Ice Lake and below have slow gather due to Gather Data Sampling
* mitigation. */ if ((rval & AV_CPU_FLAG_AVX2) && family == 6 && model < 143)
rval |= AV_CPU_FLAG_SLOW_GATHER;
}
#endif/* cpuid */
return rval;
}
size_t ff_get_cpu_max_align_x86(void)
{ int flags = av_get_cpu_flags();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.