diff --git a/cpuid.go b/cpuid.go index 3ff7286..665d5ac 100644 --- a/cpuid.go +++ b/cpuid.go @@ -159,7 +159,6 @@ const ( RDTSCP // RDTSCP Instruction RTM // Restricted Transactional Memory RTM_ALWAYS_ABORT // Indicates that the loaded microcode is forcing RTM abort. - SCE // SYSENTER and SYSEXIT instructions SERIALIZE // Serialize Instruction Execution SEV // AMD Secure Encrypted Virtualization supported SEV_64BIT // AMD SEV guest execution only allowed from a 64-bit host @@ -190,6 +189,8 @@ const ( SVMNP // AMD SVM nested paging SVMPF // SVM pause intercept filter. Indicates support for the pause intercept filter SVMPFT // SVM PAUSE filter threshold. Indicates support for the PAUSE filter cycle count threshold + SYSCALL // System-Call Extension (SCE): SYSCALL and SYSRET instructions. + SYSEE // SYSENTER and SYSEXIT instructions TBM // AMD Trailing Bit Manipulation TME // Intel Total Memory Encryption. The following MSRs are supported: IA32_TME_CAPABILITY, IA32_TME_ACTIVATE, IA32_TME_EXCLUDE_MASK, and IA32_TME_EXCLUDE_BASE. TSCRATEMSR // MSR based TSC rate control. Indicates support for MSR TSC ratio MSRC000_0104 @@ -360,11 +361,21 @@ func (c CPUInfo) Has(id FeatureID) bool { return c.featureSet.inSet(id) } +// AnyOf returns whether the CPU supports one or more of the requested features. +func (c CPUInfo) AnyOf(ids ...FeatureID) bool { + for _, id := range ids { + if c.featureSet.inSet(id) { + return true + } + } + return false +} + // https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels -var level1Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2) -var level2Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3) -var level3Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE) -var level4Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE, AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL) +var level1Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2) +var level2Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3) +var level3Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE) +var level4Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE, AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL) // X64Level returns the microarchitecture level detected on the CPU. // If features are lacking or non x64 mode, 0 is returned. @@ -993,7 +1004,7 @@ func support() flagSet { _, _, c, d := cpuid(1) fs.setIf((d&(1<<0)) != 0, X87) fs.setIf((d&(1<<8)) != 0, CMPXCHG8) - fs.setIf((d&(1<<11)) != 0, SCE) + fs.setIf((d&(1<<11)) != 0, SYSEE) fs.setIf((d&(1<<15)) != 0, CMOV) fs.setIf((d&(1<<22)) != 0, MMXEXT) fs.setIf((d&(1<<23)) != 0, MMX) @@ -1172,12 +1183,15 @@ func support() flagSet { fs.setIf((c&(1<<10)) != 0, IBS) // EDX - fs.setIf((d&(1<<31)) != 0, AMD3DNOW) - fs.setIf((d&(1<<30)) != 0, AMD3DNOWEXT) - fs.setIf((d&(1<<23)) != 0, MMX) - fs.setIf((d&(1<<22)) != 0, MMXEXT) + fs.setIf(d&(1<<11) != 0, SYSCALL) fs.setIf(d&(1<<20) != 0, NX) + fs.setIf(d&(1<<22) != 0, MMXEXT) + fs.setIf(d&(1<<23) != 0, MMX) + fs.setIf(d&(1<<24) != 0, FXSR) + fs.setIf(d&(1<<25) != 0, FXSROPT) fs.setIf(d&(1<<27) != 0, RDTSCP) + fs.setIf(d&(1<<30) != 0, AMD3DNOWEXT) + fs.setIf(d&(1<<31) != 0, AMD3DNOW) /* XOP and FMA4 use the AVX instruction coding scheme, so they can't be * used unless the OS has AVX support. */ diff --git a/featureid_string.go b/featureid_string.go index a9b3e36..fd892dd 100644 --- a/featureid_string.go +++ b/featureid_string.go @@ -99,88 +99,89 @@ func _() { _ = x[RDTSCP-89] _ = x[RTM-90] _ = x[RTM_ALWAYS_ABORT-91] - _ = x[SCE-92] - _ = x[SERIALIZE-93] - _ = x[SEV-94] - _ = x[SEV_64BIT-95] - _ = x[SEV_ALTERNATIVE-96] - _ = x[SEV_DEBUGSWAP-97] - _ = x[SEV_ES-98] - _ = x[SEV_RESTRICTED-99] - _ = x[SEV_SNP-100] - _ = x[SGX-101] - _ = x[SGXLC-102] - _ = x[SHA-103] - _ = x[SME-104] - _ = x[SME_COHERENT-105] - _ = x[SSE-106] - _ = x[SSE2-107] - _ = x[SSE3-108] - _ = x[SSE4-109] - _ = x[SSE42-110] - _ = x[SSE4A-111] - _ = x[SSSE3-112] - _ = x[STIBP-113] - _ = x[STOSB_SHORT-114] - _ = x[SUCCOR-115] - _ = x[SVM-116] - _ = x[SVMDA-117] - _ = x[SVMFBASID-118] - _ = x[SVML-119] - _ = x[SVMNP-120] - _ = x[SVMPF-121] - _ = x[SVMPFT-122] - _ = x[TBM-123] - _ = x[TME-124] - _ = x[TSCRATEMSR-125] - _ = x[TSXLDTRK-126] - _ = x[VAES-127] - _ = x[VMCBCLEAN-128] - _ = x[VMPL-129] - _ = x[VMSA_REGPROT-130] - _ = x[VMX-131] - _ = x[VPCLMULQDQ-132] - _ = x[VTE-133] - _ = x[WAITPKG-134] - _ = x[WBNOINVD-135] - _ = x[X87-136] - _ = x[XGETBV1-137] - _ = x[XOP-138] - _ = x[XSAVE-139] - _ = x[XSAVEC-140] - _ = x[XSAVEOPT-141] - _ = x[XSAVES-142] - _ = x[AESARM-143] - _ = x[ARMCPUID-144] - _ = x[ASIMD-145] - _ = x[ASIMDDP-146] - _ = x[ASIMDHP-147] - _ = x[ASIMDRDM-148] - _ = x[ATOMICS-149] - _ = x[CRC32-150] - _ = x[DCPOP-151] - _ = x[EVTSTRM-152] - _ = x[FCMA-153] - _ = x[FP-154] - _ = x[FPHP-155] - _ = x[GPA-156] - _ = x[JSCVT-157] - _ = x[LRCPC-158] - _ = x[PMULL-159] - _ = x[SHA1-160] - _ = x[SHA2-161] - _ = x[SHA3-162] - _ = x[SHA512-163] - _ = x[SM3-164] - _ = x[SM4-165] - _ = x[SVE-166] - _ = x[lastID-167] + _ = x[SERIALIZE-92] + _ = x[SEV-93] + _ = x[SEV_64BIT-94] + _ = x[SEV_ALTERNATIVE-95] + _ = x[SEV_DEBUGSWAP-96] + _ = x[SEV_ES-97] + _ = x[SEV_RESTRICTED-98] + _ = x[SEV_SNP-99] + _ = x[SGX-100] + _ = x[SGXLC-101] + _ = x[SHA-102] + _ = x[SME-103] + _ = x[SME_COHERENT-104] + _ = x[SSE-105] + _ = x[SSE2-106] + _ = x[SSE3-107] + _ = x[SSE4-108] + _ = x[SSE42-109] + _ = x[SSE4A-110] + _ = x[SSSE3-111] + _ = x[STIBP-112] + _ = x[STOSB_SHORT-113] + _ = x[SUCCOR-114] + _ = x[SVM-115] + _ = x[SVMDA-116] + _ = x[SVMFBASID-117] + _ = x[SVML-118] + _ = x[SVMNP-119] + _ = x[SVMPF-120] + _ = x[SVMPFT-121] + _ = x[SYSCALL-122] + _ = x[SYSEE-123] + _ = x[TBM-124] + _ = x[TME-125] + _ = x[TSCRATEMSR-126] + _ = x[TSXLDTRK-127] + _ = x[VAES-128] + _ = x[VMCBCLEAN-129] + _ = x[VMPL-130] + _ = x[VMSA_REGPROT-131] + _ = x[VMX-132] + _ = x[VPCLMULQDQ-133] + _ = x[VTE-134] + _ = x[WAITPKG-135] + _ = x[WBNOINVD-136] + _ = x[X87-137] + _ = x[XGETBV1-138] + _ = x[XOP-139] + _ = x[XSAVE-140] + _ = x[XSAVEC-141] + _ = x[XSAVEOPT-142] + _ = x[XSAVES-143] + _ = x[AESARM-144] + _ = x[ARMCPUID-145] + _ = x[ASIMD-146] + _ = x[ASIMDDP-147] + _ = x[ASIMDHP-148] + _ = x[ASIMDRDM-149] + _ = x[ATOMICS-150] + _ = x[CRC32-151] + _ = x[DCPOP-152] + _ = x[EVTSTRM-153] + _ = x[FCMA-154] + _ = x[FP-155] + _ = x[FPHP-156] + _ = x[GPA-157] + _ = x[JSCVT-158] + _ = x[LRCPC-159] + _ = x[PMULL-160] + _ = x[SHA1-161] + _ = x[SHA2-162] + _ = x[SHA3-163] + _ = x[SHA512-164] + _ = x[SM3-165] + _ = x[SM4-166] + _ = x[SVE-167] + _ = x[lastID-168] _ = x[firstID-0] } -const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXINT8AMXTILEAVXAVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXSLOWAVXVNNIBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCX16ENQCMDERMSF16CFMA3FMA4FXSRFXSROPTGFNIHLEHRESETHTTHWAHYPERVISORIBPBIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_PREVENTHOSTINT_WBINVDINVLPGBLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCOMMITMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMPXMSRIRCMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTRDPRURDRANDRDSEEDRDTSCPRTMRTM_ALWAYS_ABORTSCESERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTTBMTMETSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID" +const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXINT8AMXTILEAVXAVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXSLOWAVXVNNIBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCX16ENQCMDERMSF16CFMA3FMA4FXSRFXSROPTGFNIHLEHRESETHTTHWAHYPERVISORIBPBIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_PREVENTHOSTINT_WBINVDINVLPGBLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCOMMITMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMPXMSRIRCMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTRDPRURDRANDRDSEEDRDTSCPRTMRTM_ALWAYS_ABORTSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTMETSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID" -var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 58, 62, 72, 84, 92, 100, 108, 116, 123, 133, 143, 151, 161, 172, 180, 190, 208, 223, 230, 237, 241, 245, 251, 256, 264, 269, 275, 279, 297, 305, 312, 316, 322, 326, 330, 334, 338, 342, 349, 353, 356, 362, 365, 368, 378, 382, 385, 395, 406, 412, 420, 431, 439, 451, 467, 482, 492, 499, 503, 506, 513, 518, 529, 536, 539, 545, 550, 559, 566, 574, 577, 583, 596, 601, 603, 610, 617, 623, 628, 634, 640, 646, 649, 665, 668, 677, 680, 689, 704, 717, 723, 737, 744, 747, 752, 755, 758, 770, 773, 777, 781, 785, 790, 795, 800, 805, 816, 822, 825, 830, 839, 843, 848, 853, 859, 862, 865, 875, 883, 887, 896, 900, 912, 915, 925, 928, 935, 943, 946, 953, 956, 961, 967, 975, 981, 987, 995, 1000, 1007, 1014, 1022, 1029, 1034, 1039, 1046, 1050, 1052, 1056, 1059, 1064, 1069, 1074, 1078, 1082, 1086, 1092, 1095, 1098, 1101, 1107} +var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 58, 62, 72, 84, 92, 100, 108, 116, 123, 133, 143, 151, 161, 172, 180, 190, 208, 223, 230, 237, 241, 245, 251, 256, 264, 269, 275, 279, 297, 305, 312, 316, 322, 326, 330, 334, 338, 342, 349, 353, 356, 362, 365, 368, 378, 382, 385, 395, 406, 412, 420, 431, 439, 451, 467, 482, 492, 499, 503, 506, 513, 518, 529, 536, 539, 545, 550, 559, 566, 574, 577, 583, 596, 601, 603, 610, 617, 623, 628, 634, 640, 646, 649, 665, 674, 677, 686, 701, 714, 720, 734, 741, 744, 749, 752, 755, 767, 770, 774, 778, 782, 787, 792, 797, 802, 813, 819, 822, 827, 836, 840, 845, 850, 856, 863, 868, 871, 874, 884, 892, 896, 905, 909, 921, 924, 934, 937, 944, 952, 955, 962, 965, 970, 976, 984, 990, 996, 1004, 1009, 1016, 1023, 1031, 1038, 1043, 1048, 1055, 1059, 1061, 1065, 1068, 1073, 1078, 1083, 1087, 1091, 1095, 1101, 1104, 1107, 1110, 1116} func (i FeatureID) String() string { if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) {