1// Generated, DO NOT EDIT, 2// but copy it to your own project and rename the package. 3// See more at http://github.com/klauspost/cpuid 4 5package cpuid 6 7import ( 8 "math" 9 "strings" 10) 11 12// AMD refererence: https://www.amd.com/system/files/TechDocs/25481.pdf 13// and Processor Programming Reference (PPR) 14 15// Vendor is a representation of a CPU vendor. 16type vendor int 17 18const ( 19 other vendor = iota 20 intel 21 amd 22 via 23 transmeta 24 nsc 25 kvm // Kernel-based Virtual Machine 26 msvm // Microsoft Hyper-V or Windows Virtual PC 27 vmware 28 xenhvm 29 bhyve 30 hygon 31 sis 32 rdc 33) 34 35const ( 36 cmov = 1 << iota // i686 CMOV 37 nx // NX (No-Execute) bit 38 amd3dnow // AMD 3DNOW 39 amd3dnowext // AMD 3DNowExt 40 mmx // standard MMX 41 mmxext // SSE integer functions or AMD MMX ext 42 sse // SSE functions 43 sse2 // P4 SSE functions 44 sse3 // Prescott SSE3 functions 45 ssse3 // Conroe SSSE3 functions 46 sse4 // Penryn SSE4.1 functions 47 sse4a // AMD Barcelona microarchitecture SSE4a instructions 48 sse42 // Nehalem SSE4.2 functions 49 avx // AVX functions 50 avx2 // AVX2 functions 51 fma3 // Intel FMA 3 52 fma4 // Bulldozer FMA4 functions 53 xop // Bulldozer XOP functions 54 f16c // Half-precision floating-point conversion 55 bmi1 // Bit Manipulation Instruction Set 1 56 bmi2 // Bit Manipulation Instruction Set 2 57 tbm // AMD Trailing Bit Manipulation 58 lzcnt // LZCNT instruction 59 popcnt // POPCNT instruction 60 aesni // Advanced Encryption Standard New Instructions 61 clmul // Carry-less Multiplication 62 htt // Hyperthreading (enabled) 63 hle // Hardware Lock Elision 64 rtm // Restricted Transactional Memory 65 rdrand // RDRAND instruction is available 66 rdseed // RDSEED instruction is available 67 adx // Intel ADX (Multi-Precision Add-Carry Instruction Extensions) 68 sha // Intel SHA Extensions 69 avx512f // AVX-512 Foundation 70 avx512dq // AVX-512 Doubleword and Quadword Instructions 71 avx512ifma // AVX-512 Integer Fused Multiply-Add Instructions 72 avx512pf // AVX-512 Prefetch Instructions 73 avx512er // AVX-512 Exponential and Reciprocal Instructions 74 avx512cd // AVX-512 Conflict Detection Instructions 75 avx512bw // AVX-512 Byte and Word Instructions 76 avx512vl // AVX-512 Vector Length Extensions 77 avx512vbmi // AVX-512 Vector Bit Manipulation Instructions 78 avx512vbmi2 // AVX-512 Vector Bit Manipulation Instructions, Version 2 79 avx512vnni // AVX-512 Vector Neural Network Instructions 80 avx512vpopcntdq // AVX-512 Vector Population Count Doubleword and Quadword 81 gfni // Galois Field New Instructions 82 vaes // Vector AES 83 avx512bitalg // AVX-512 Bit Algorithms 84 vpclmulqdq // Carry-Less Multiplication Quadword 85 avx512bf16 // AVX-512 BFLOAT16 Instructions 86 avx512vp2intersect // AVX-512 Intersect for D/Q 87 mpx // Intel MPX (Memory Protection Extensions) 88 erms // Enhanced REP MOVSB/STOSB 89 rdtscp // RDTSCP Instruction 90 cx16 // CMPXCHG16B Instruction 91 sgx // Software Guard Extensions 92 sgxlc // Software Guard Extensions Launch Control 93 ibpb // Indirect Branch Restricted Speculation (IBRS) and Indirect Branch Predictor Barrier (IBPB) 94 stibp // Single Thread Indirect Branch Predictors 95 vmx // Virtual Machine Extensions 96 97 // Performance indicators 98 sse2slow // SSE2 is supported, but usually not faster 99 sse3slow // SSE3 is supported, but usually not faster 100 atom // Atom processor, some SSSE3 instructions are slower 101) 102 103var flagNames = map[flags]string{ 104 cmov: "CMOV", // i686 CMOV 105 nx: "NX", // NX (No-Execute) bit 106 amd3dnow: "AMD3DNOW", // AMD 3DNOW 107 amd3dnowext: "AMD3DNOWEXT", // AMD 3DNowExt 108 mmx: "MMX", // Standard MMX 109 mmxext: "MMXEXT", // SSE integer functions or AMD MMX ext 110 sse: "SSE", // SSE functions 111 sse2: "SSE2", // P4 SSE2 functions 112 sse3: "SSE3", // Prescott SSE3 functions 113 ssse3: "SSSE3", // Conroe SSSE3 functions 114 sse4: "SSE4.1", // Penryn SSE4.1 functions 115 sse4a: "SSE4A", // AMD Barcelona microarchitecture SSE4a instructions 116 sse42: "SSE4.2", // Nehalem SSE4.2 functions 117 avx: "AVX", // AVX functions 118 avx2: "AVX2", // AVX functions 119 fma3: "FMA3", // Intel FMA 3 120 fma4: "FMA4", // Bulldozer FMA4 functions 121 xop: "XOP", // Bulldozer XOP functions 122 f16c: "F16C", // Half-precision floating-point conversion 123 bmi1: "BMI1", // Bit Manipulation Instruction Set 1 124 bmi2: "BMI2", // Bit Manipulation Instruction Set 2 125 tbm: "TBM", // AMD Trailing Bit Manipulation 126 lzcnt: "LZCNT", // LZCNT instruction 127 popcnt: "POPCNT", // POPCNT instruction 128 aesni: "AESNI", // Advanced Encryption Standard New Instructions 129 clmul: "CLMUL", // Carry-less Multiplication 130 htt: "HTT", // Hyperthreading (enabled) 131 hle: "HLE", // Hardware Lock Elision 132 rtm: "RTM", // Restricted Transactional Memory 133 rdrand: "RDRAND", // RDRAND instruction is available 134 rdseed: "RDSEED", // RDSEED instruction is available 135 adx: "ADX", // Intel ADX (Multi-Precision Add-Carry Instruction Extensions) 136 sha: "SHA", // Intel SHA Extensions 137 avx512f: "AVX512F", // AVX-512 Foundation 138 avx512dq: "AVX512DQ", // AVX-512 Doubleword and Quadword Instructions 139 avx512ifma: "AVX512IFMA", // AVX-512 Integer Fused Multiply-Add Instructions 140 avx512pf: "AVX512PF", // AVX-512 Prefetch Instructions 141 avx512er: "AVX512ER", // AVX-512 Exponential and Reciprocal Instructions 142 avx512cd: "AVX512CD", // AVX-512 Conflict Detection Instructions 143 avx512bw: "AVX512BW", // AVX-512 Byte and Word Instructions 144 avx512vl: "AVX512VL", // AVX-512 Vector Length Extensions 145 avx512vbmi: "AVX512VBMI", // AVX-512 Vector Bit Manipulation Instructions 146 avx512vbmi2: "AVX512VBMI2", // AVX-512 Vector Bit Manipulation Instructions, Version 2 147 avx512vnni: "AVX512VNNI", // AVX-512 Vector Neural Network Instructions 148 avx512vpopcntdq: "AVX512VPOPCNTDQ", // AVX-512 Vector Population Count Doubleword and Quadword 149 gfni: "GFNI", // Galois Field New Instructions 150 vaes: "VAES", // Vector AES 151 avx512bitalg: "AVX512BITALG", // AVX-512 Bit Algorithms 152 vpclmulqdq: "VPCLMULQDQ", // Carry-Less Multiplication Quadword 153 avx512bf16: "AVX512BF16", // AVX-512 BFLOAT16 Instruction 154 avx512vp2intersect: "AVX512VP2INTERSECT", // AVX-512 Intersect for D/Q 155 mpx: "MPX", // Intel MPX (Memory Protection Extensions) 156 erms: "ERMS", // Enhanced REP MOVSB/STOSB 157 rdtscp: "RDTSCP", // RDTSCP Instruction 158 cx16: "CX16", // CMPXCHG16B Instruction 159 sgx: "SGX", // Software Guard Extensions 160 sgxlc: "SGXLC", // Software Guard Extensions Launch Control 161 ibpb: "IBPB", // Indirect Branch Restricted Speculation and Indirect Branch Predictor Barrier 162 stibp: "STIBP", // Single Thread Indirect Branch Predictors 163 vmx: "VMX", // Virtual Machine Extensions 164 165 // Performance indicators 166 sse2slow: "SSE2SLOW", // SSE2 supported, but usually not faster 167 sse3slow: "SSE3SLOW", // SSE3 supported, but usually not faster 168 atom: "ATOM", // Atom processor, some SSSE3 instructions are slower 169 170} 171 172/* all special features for arm64 should be defined here */ 173const ( 174 /* extension instructions */ 175 fp armflags = 1 << iota 176 asimd 177 evtstrm 178 aes 179 pmull 180 sha1 181 sha2 182 crc32 183 atomics 184 fphp 185 asimdhp 186 armcpuid 187 asimdrdm 188 jscvt 189 fcma 190 lrcpc 191 dcpop 192 sha3 193 sm3 194 sm4 195 asimddp 196 sha512 197 sve 198 gpa 199) 200 201var flagNamesArm = map[armflags]string{ 202 fp: "FP", // Single-precision and double-precision floating point 203 asimd: "ASIMD", // Advanced SIMD 204 evtstrm: "EVTSTRM", // Generic timer 205 aes: "AES", // AES instructions 206 pmull: "PMULL", // Polynomial Multiply instructions (PMULL/PMULL2) 207 sha1: "SHA1", // SHA-1 instructions (SHA1C, etc) 208 sha2: "SHA2", // SHA-2 instructions (SHA256H, etc) 209 crc32: "CRC32", // CRC32/CRC32C instructions 210 atomics: "ATOMICS", // Large System Extensions (LSE) 211 fphp: "FPHP", // Half-precision floating point 212 asimdhp: "ASIMDHP", // Advanced SIMD half-precision floating point 213 armcpuid: "CPUID", // Some CPU ID registers readable at user-level 214 asimdrdm: "ASIMDRDM", // Rounding Double Multiply Accumulate/Subtract (SQRDMLAH/SQRDMLSH) 215 jscvt: "JSCVT", // Javascript-style double->int convert (FJCVTZS) 216 fcma: "FCMA", // Floatin point complex number addition and multiplication 217 lrcpc: "LRCPC", // Weaker release consistency (LDAPR, etc) 218 dcpop: "DCPOP", // Data cache clean to Point of Persistence (DC CVAP) 219 sha3: "SHA3", // SHA-3 instructions (EOR3, RAXI, XAR, BCAX) 220 sm3: "SM3", // SM3 instructions 221 sm4: "SM4", // SM4 instructions 222 asimddp: "ASIMDDP", // SIMD Dot Product 223 sha512: "SHA512", // SHA512 instructions 224 sve: "SVE", // Scalable Vector Extension 225 gpa: "GPA", // Generic Pointer Authentication 226} 227 228// CPUInfo contains information about the detected system CPU. 229type cpuInfo struct { 230 brandname string // Brand name reported by the CPU 231 vendorid vendor // Comparable CPU vendor ID 232 vendorstring string // Raw vendor string. 233 features flags // Features of the CPU (x64) 234 arm armflags // Features of the CPU (arm) 235 physicalcores int // Number of physical processor cores in your CPU. Will be 0 if undetectable. 236 threadspercore int // Number of threads per physical core. Will be 1 if undetectable. 237 logicalcores int // Number of physical cores times threads that can run on each core through the use of hyperthreading. Will be 0 if undetectable. 238 family int // CPU family number 239 model int // CPU model number 240 cacheline int // Cache line size in bytes. Will be 0 if undetectable. 241 hz int64 // Clock speed, if known 242 cache struct { 243 l1i int // L1 Instruction Cache (per core or shared). Will be -1 if undetected 244 l1d int // L1 Data Cache (per core or shared). Will be -1 if undetected 245 l2 int // L2 Cache (per core or shared). Will be -1 if undetected 246 l3 int // L3 Cache (per core, per ccx or shared). Will be -1 if undetected 247 } 248 sgx sgxsupport 249 maxFunc uint32 250 maxExFunc uint32 251} 252 253var cpuid func(op uint32) (eax, ebx, ecx, edx uint32) 254var cpuidex func(op, op2 uint32) (eax, ebx, ecx, edx uint32) 255var xgetbv func(index uint32) (eax, edx uint32) 256var rdtscpAsm func() (eax, ebx, ecx, edx uint32) 257 258// CPU contains information about the CPU as detected on startup, 259// or when Detect last was called. 260// 261// Use this as the primary entry point to you data. 262var cpu cpuInfo 263 264func init() { 265 initCPU() 266 detect() 267} 268 269// Detect will re-detect current CPU info. 270// This will replace the content of the exported CPU variable. 271// 272// Unless you expect the CPU to change while you are running your program 273// you should not need to call this function. 274// If you call this, you must ensure that no other goroutine is accessing the 275// exported CPU variable. 276func detect() { 277 // Set defaults 278 cpu.threadspercore = 1 279 cpu.cache.l1i = -1 280 cpu.cache.l1d = -1 281 cpu.cache.l2 = -1 282 cpu.cache.l3 = -1 283 addInfo(&cpu) 284} 285 286// Generated here: http://play.golang.org/p/BxFH2Gdc0G 287 288// Cmov indicates support of CMOV instructions 289func (c cpuInfo) cmov() bool { 290 return c.features&cmov != 0 291} 292 293// Amd3dnow indicates support of AMD 3DNOW! instructions 294func (c cpuInfo) amd3dnow() bool { 295 return c.features&amd3dnow != 0 296} 297 298// Amd3dnowExt indicates support of AMD 3DNOW! Extended instructions 299func (c cpuInfo) amd3dnowext() bool { 300 return c.features&amd3dnowext != 0 301} 302 303// VMX indicates support of VMX 304func (c cpuInfo) vmx() bool { 305 return c.features&vmx != 0 306} 307 308// MMX indicates support of MMX instructions 309func (c cpuInfo) mmx() bool { 310 return c.features&mmx != 0 311} 312 313// MMXExt indicates support of MMXEXT instructions 314// (SSE integer functions or AMD MMX ext) 315func (c cpuInfo) mmxext() bool { 316 return c.features&mmxext != 0 317} 318 319// SSE indicates support of SSE instructions 320func (c cpuInfo) sse() bool { 321 return c.features&sse != 0 322} 323 324// SSE2 indicates support of SSE 2 instructions 325func (c cpuInfo) sse2() bool { 326 return c.features&sse2 != 0 327} 328 329// SSE3 indicates support of SSE 3 instructions 330func (c cpuInfo) sse3() bool { 331 return c.features&sse3 != 0 332} 333 334// SSSE3 indicates support of SSSE 3 instructions 335func (c cpuInfo) ssse3() bool { 336 return c.features&ssse3 != 0 337} 338 339// SSE4 indicates support of SSE 4 (also called SSE 4.1) instructions 340func (c cpuInfo) sse4() bool { 341 return c.features&sse4 != 0 342} 343 344// SSE42 indicates support of SSE4.2 instructions 345func (c cpuInfo) sse42() bool { 346 return c.features&sse42 != 0 347} 348 349// AVX indicates support of AVX instructions 350// and operating system support of AVX instructions 351func (c cpuInfo) avx() bool { 352 return c.features&avx != 0 353} 354 355// AVX2 indicates support of AVX2 instructions 356func (c cpuInfo) avx2() bool { 357 return c.features&avx2 != 0 358} 359 360// FMA3 indicates support of FMA3 instructions 361func (c cpuInfo) fma3() bool { 362 return c.features&fma3 != 0 363} 364 365// FMA4 indicates support of FMA4 instructions 366func (c cpuInfo) fma4() bool { 367 return c.features&fma4 != 0 368} 369 370// XOP indicates support of XOP instructions 371func (c cpuInfo) xop() bool { 372 return c.features&xop != 0 373} 374 375// F16C indicates support of F16C instructions 376func (c cpuInfo) f16c() bool { 377 return c.features&f16c != 0 378} 379 380// BMI1 indicates support of BMI1 instructions 381func (c cpuInfo) bmi1() bool { 382 return c.features&bmi1 != 0 383} 384 385// BMI2 indicates support of BMI2 instructions 386func (c cpuInfo) bmi2() bool { 387 return c.features&bmi2 != 0 388} 389 390// TBM indicates support of TBM instructions 391// (AMD Trailing Bit Manipulation) 392func (c cpuInfo) tbm() bool { 393 return c.features&tbm != 0 394} 395 396// Lzcnt indicates support of LZCNT instruction 397func (c cpuInfo) lzcnt() bool { 398 return c.features&lzcnt != 0 399} 400 401// Popcnt indicates support of POPCNT instruction 402func (c cpuInfo) popcnt() bool { 403 return c.features&popcnt != 0 404} 405 406// HTT indicates the processor has Hyperthreading enabled 407func (c cpuInfo) htt() bool { 408 return c.features&htt != 0 409} 410 411// SSE2Slow indicates that SSE2 may be slow on this processor 412func (c cpuInfo) sse2slow() bool { 413 return c.features&sse2slow != 0 414} 415 416// SSE3Slow indicates that SSE3 may be slow on this processor 417func (c cpuInfo) sse3slow() bool { 418 return c.features&sse3slow != 0 419} 420 421// AesNi indicates support of AES-NI instructions 422// (Advanced Encryption Standard New Instructions) 423func (c cpuInfo) aesni() bool { 424 return c.features&aesni != 0 425} 426 427// Clmul indicates support of CLMUL instructions 428// (Carry-less Multiplication) 429func (c cpuInfo) clmul() bool { 430 return c.features&clmul != 0 431} 432 433// NX indicates support of NX (No-Execute) bit 434func (c cpuInfo) nx() bool { 435 return c.features&nx != 0 436} 437 438// SSE4A indicates support of AMD Barcelona microarchitecture SSE4a instructions 439func (c cpuInfo) sse4a() bool { 440 return c.features&sse4a != 0 441} 442 443// HLE indicates support of Hardware Lock Elision 444func (c cpuInfo) hle() bool { 445 return c.features&hle != 0 446} 447 448// RTM indicates support of Restricted Transactional Memory 449func (c cpuInfo) rtm() bool { 450 return c.features&rtm != 0 451} 452 453// Rdrand indicates support of RDRAND instruction is available 454func (c cpuInfo) rdrand() bool { 455 return c.features&rdrand != 0 456} 457 458// Rdseed indicates support of RDSEED instruction is available 459func (c cpuInfo) rdseed() bool { 460 return c.features&rdseed != 0 461} 462 463// ADX indicates support of Intel ADX (Multi-Precision Add-Carry Instruction Extensions) 464func (c cpuInfo) adx() bool { 465 return c.features&adx != 0 466} 467 468// SHA indicates support of Intel SHA Extensions 469func (c cpuInfo) sha() bool { 470 return c.features&sha != 0 471} 472 473// AVX512F indicates support of AVX-512 Foundation 474func (c cpuInfo) avx512f() bool { 475 return c.features&avx512f != 0 476} 477 478// AVX512DQ indicates support of AVX-512 Doubleword and Quadword Instructions 479func (c cpuInfo) avx512dq() bool { 480 return c.features&avx512dq != 0 481} 482 483// AVX512IFMA indicates support of AVX-512 Integer Fused Multiply-Add Instructions 484func (c cpuInfo) avx512ifma() bool { 485 return c.features&avx512ifma != 0 486} 487 488// AVX512PF indicates support of AVX-512 Prefetch Instructions 489func (c cpuInfo) avx512pf() bool { 490 return c.features&avx512pf != 0 491} 492 493// AVX512ER indicates support of AVX-512 Exponential and Reciprocal Instructions 494func (c cpuInfo) avx512er() bool { 495 return c.features&avx512er != 0 496} 497 498// AVX512CD indicates support of AVX-512 Conflict Detection Instructions 499func (c cpuInfo) avx512cd() bool { 500 return c.features&avx512cd != 0 501} 502 503// AVX512BW indicates support of AVX-512 Byte and Word Instructions 504func (c cpuInfo) avx512bw() bool { 505 return c.features&avx512bw != 0 506} 507 508// AVX512VL indicates support of AVX-512 Vector Length Extensions 509func (c cpuInfo) avx512vl() bool { 510 return c.features&avx512vl != 0 511} 512 513// AVX512VBMI indicates support of AVX-512 Vector Bit Manipulation Instructions 514func (c cpuInfo) avx512vbmi() bool { 515 return c.features&avx512vbmi != 0 516} 517 518// AVX512VBMI2 indicates support of AVX-512 Vector Bit Manipulation Instructions, Version 2 519func (c cpuInfo) avx512vbmi2() bool { 520 return c.features&avx512vbmi2 != 0 521} 522 523// AVX512VNNI indicates support of AVX-512 Vector Neural Network Instructions 524func (c cpuInfo) avx512vnni() bool { 525 return c.features&avx512vnni != 0 526} 527 528// AVX512VPOPCNTDQ indicates support of AVX-512 Vector Population Count Doubleword and Quadword 529func (c cpuInfo) avx512vpopcntdq() bool { 530 return c.features&avx512vpopcntdq != 0 531} 532 533// GFNI indicates support of Galois Field New Instructions 534func (c cpuInfo) gfni() bool { 535 return c.features&gfni != 0 536} 537 538// VAES indicates support of Vector AES 539func (c cpuInfo) vaes() bool { 540 return c.features&vaes != 0 541} 542 543// AVX512BITALG indicates support of AVX-512 Bit Algorithms 544func (c cpuInfo) avx512bitalg() bool { 545 return c.features&avx512bitalg != 0 546} 547 548// VPCLMULQDQ indicates support of Carry-Less Multiplication Quadword 549func (c cpuInfo) vpclmulqdq() bool { 550 return c.features&vpclmulqdq != 0 551} 552 553// AVX512BF16 indicates support of 554func (c cpuInfo) avx512bf16() bool { 555 return c.features&avx512bf16 != 0 556} 557 558// AVX512VP2INTERSECT indicates support of 559func (c cpuInfo) avx512vp2intersect() bool { 560 return c.features&avx512vp2intersect != 0 561} 562 563// MPX indicates support of Intel MPX (Memory Protection Extensions) 564func (c cpuInfo) mpx() bool { 565 return c.features&mpx != 0 566} 567 568// ERMS indicates support of Enhanced REP MOVSB/STOSB 569func (c cpuInfo) erms() bool { 570 return c.features&erms != 0 571} 572 573// RDTSCP Instruction is available. 574func (c cpuInfo) rdtscp() bool { 575 return c.features&rdtscp != 0 576} 577 578// CX16 indicates if CMPXCHG16B instruction is available. 579func (c cpuInfo) cx16() bool { 580 return c.features&cx16 != 0 581} 582 583// TSX is split into HLE (Hardware Lock Elision) and RTM (Restricted Transactional Memory) detection. 584// So TSX simply checks that. 585func (c cpuInfo) tsx() bool { 586 return c.features&(hle|rtm) == hle|rtm 587} 588 589// Atom indicates an Atom processor 590func (c cpuInfo) atom() bool { 591 return c.features&atom != 0 592} 593 594// Intel returns true if vendor is recognized as Intel 595func (c cpuInfo) intel() bool { 596 return c.vendorid == intel 597} 598 599// AMD returns true if vendor is recognized as AMD 600func (c cpuInfo) amd() bool { 601 return c.vendorid == amd 602} 603 604// Hygon returns true if vendor is recognized as Hygon 605func (c cpuInfo) hygon() bool { 606 return c.vendorid == hygon 607} 608 609// Transmeta returns true if vendor is recognized as Transmeta 610func (c cpuInfo) transmeta() bool { 611 return c.vendorid == transmeta 612} 613 614// NSC returns true if vendor is recognized as National Semiconductor 615func (c cpuInfo) nsc() bool { 616 return c.vendorid == nsc 617} 618 619// VIA returns true if vendor is recognized as VIA 620func (c cpuInfo) via() bool { 621 return c.vendorid == via 622} 623 624// RTCounter returns the 64-bit time-stamp counter 625// Uses the RDTSCP instruction. The value 0 is returned 626// if the CPU does not support the instruction. 627func (c cpuInfo) rtcounter() uint64 { 628 if !c.rdtscp() { 629 return 0 630 } 631 a, _, _, d := rdtscpAsm() 632 return uint64(a) | (uint64(d) << 32) 633} 634 635// Ia32TscAux returns the IA32_TSC_AUX part of the RDTSCP. 636// This variable is OS dependent, but on Linux contains information 637// about the current cpu/core the code is running on. 638// If the RDTSCP instruction isn't supported on the CPU, the value 0 is returned. 639func (c cpuInfo) ia32tscaux() uint32 { 640 if !c.rdtscp() { 641 return 0 642 } 643 _, _, ecx, _ := rdtscpAsm() 644 return ecx 645} 646 647// LogicalCPU will return the Logical CPU the code is currently executing on. 648// This is likely to change when the OS re-schedules the running thread 649// to another CPU. 650// If the current core cannot be detected, -1 will be returned. 651func (c cpuInfo) logicalcpu() int { 652 if c.maxFunc < 1 { 653 return -1 654 } 655 _, ebx, _, _ := cpuid(1) 656 return int(ebx >> 24) 657} 658 659// hertz tries to compute the clock speed of the CPU. If leaf 15 is 660// supported, use it, otherwise parse the brand string. Yes, really. 661func hertz(model string) int64 { 662 mfi := maxFunctionID() 663 if mfi >= 0x15 { 664 eax, ebx, ecx, _ := cpuid(0x15) 665 if eax != 0 && ebx != 0 && ecx != 0 { 666 return int64((int64(ecx) * int64(ebx)) / int64(eax)) 667 } 668 } 669 // computeHz determines the official rated speed of a CPU from its brand 670 // string. This insanity is *actually the official documented way to do 671 // this according to Intel*, prior to leaf 0x15 existing. The official 672 // documentation only shows this working for exactly `x.xx` or `xxxx` 673 // cases, e.g., `2.50GHz` or `1300MHz`; this parser will accept other 674 // sizes. 675 hz := strings.LastIndex(model, "Hz") 676 if hz < 3 { 677 return -1 678 } 679 var multiplier int64 680 switch model[hz-1] { 681 case 'M': 682 multiplier = 1000 * 1000 683 case 'G': 684 multiplier = 1000 * 1000 * 1000 685 case 'T': 686 multiplier = 1000 * 1000 * 1000 * 1000 687 } 688 if multiplier == 0 { 689 return -1 690 } 691 freq := int64(0) 692 divisor := int64(0) 693 decimalShift := int64(1) 694 var i int 695 for i = hz - 2; i >= 0 && model[i] != ' '; i-- { 696 if model[i] >= '0' && model[i] <= '9' { 697 freq += int64(model[i]-'0') * decimalShift 698 decimalShift *= 10 699 } else if model[i] == '.' { 700 if divisor != 0 { 701 return -1 702 } 703 divisor = decimalShift 704 } else { 705 return -1 706 } 707 } 708 // we didn't find a space 709 if i < 0 { 710 return -1 711 } 712 if divisor != 0 { 713 return (freq * multiplier) / divisor 714 } 715 return freq * multiplier 716} 717 718// VM Will return true if the cpu id indicates we are in 719// a virtual machine. This is only a hint, and will very likely 720// have many false negatives. 721func (c cpuInfo) vm() bool { 722 switch c.vendorid { 723 case msvm, kvm, vmware, xenhvm, bhyve: 724 return true 725 } 726 return false 727} 728 729// Flags contains detected cpu features and characteristics 730type flags uint64 731 732// ArmFlags contains detected ARM cpu features and characteristics 733type armflags uint64 734 735// String returns a string representation of the detected 736// CPU features. 737func (f flags) String() string { 738 return strings.Join(f.strings(), ",") 739} 740 741// Strings returns an array of the detected features. 742func (f flags) strings() []string { 743 r := make([]string, 0, 20) 744 for i := uint(0); i < 64; i++ { 745 key := flags(1 << i) 746 val := flagNames[key] 747 if f&key != 0 { 748 r = append(r, val) 749 } 750 } 751 return r 752} 753 754// String returns a string representation of the detected 755// CPU features. 756func (f armflags) String() string { 757 return strings.Join(f.strings(), ",") 758} 759 760// Strings returns an array of the detected features. 761func (f armflags) strings() []string { 762 r := make([]string, 0, 20) 763 for i := uint(0); i < 64; i++ { 764 key := armflags(1 << i) 765 val := flagNamesArm[key] 766 if f&key != 0 { 767 r = append(r, val) 768 } 769 } 770 return r 771} 772func maxExtendedFunction() uint32 { 773 eax, _, _, _ := cpuid(0x80000000) 774 return eax 775} 776 777func maxFunctionID() uint32 { 778 a, _, _, _ := cpuid(0) 779 return a 780} 781 782func brandName() string { 783 if maxExtendedFunction() >= 0x80000004 { 784 v := make([]uint32, 0, 48) 785 for i := uint32(0); i < 3; i++ { 786 a, b, c, d := cpuid(0x80000002 + i) 787 v = append(v, a, b, c, d) 788 } 789 return strings.Trim(string(valAsString(v...)), " ") 790 } 791 return "unknown" 792} 793 794func threadsPerCore() int { 795 mfi := maxFunctionID() 796 vend, _ := vendorID() 797 798 if mfi < 0x4 || (vend != intel && vend != amd) { 799 return 1 800 } 801 802 if mfi < 0xb { 803 if vend != intel { 804 return 1 805 } 806 _, b, _, d := cpuid(1) 807 if (d & (1 << 28)) != 0 { 808 // v will contain logical core count 809 v := (b >> 16) & 255 810 if v > 1 { 811 a4, _, _, _ := cpuid(4) 812 // physical cores 813 v2 := (a4 >> 26) + 1 814 if v2 > 0 { 815 return int(v) / int(v2) 816 } 817 } 818 } 819 return 1 820 } 821 _, b, _, _ := cpuidex(0xb, 0) 822 if b&0xffff == 0 { 823 return 1 824 } 825 return int(b & 0xffff) 826} 827 828func logicalCores() int { 829 mfi := maxFunctionID() 830 v, _ := vendorID() 831 switch v { 832 case intel: 833 // Use this on old Intel processors 834 if mfi < 0xb { 835 if mfi < 1 { 836 return 0 837 } 838 // CPUID.1:EBX[23:16] represents the maximum number of addressable IDs (initial APIC ID) 839 // that can be assigned to logical processors in a physical package. 840 // The value may not be the same as the number of logical processors that are present in the hardware of a physical package. 841 _, ebx, _, _ := cpuid(1) 842 logical := (ebx >> 16) & 0xff 843 return int(logical) 844 } 845 _, b, _, _ := cpuidex(0xb, 1) 846 return int(b & 0xffff) 847 case amd, hygon: 848 _, b, _, _ := cpuid(1) 849 return int((b >> 16) & 0xff) 850 default: 851 return 0 852 } 853} 854 855func familyModel() (int, int) { 856 if maxFunctionID() < 0x1 { 857 return 0, 0 858 } 859 eax, _, _, _ := cpuid(1) 860 family := ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff) 861 model := ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0) 862 return int(family), int(model) 863} 864 865func physicalCores() int { 866 v, _ := vendorID() 867 switch v { 868 case intel: 869 return logicalCores() / threadsPerCore() 870 case amd, hygon: 871 lc := logicalCores() 872 tpc := threadsPerCore() 873 if lc > 0 && tpc > 0 { 874 return lc / tpc 875 } 876 // The following is inaccurate on AMD EPYC 7742 64-Core Processor 877 878 if maxExtendedFunction() >= 0x80000008 { 879 _, _, c, _ := cpuid(0x80000008) 880 return int(c&0xff) + 1 881 } 882 } 883 return 0 884} 885 886// Except from http://en.wikipedia.org/wiki/CPUID#EAX.3D0:_Get_vendor_ID 887var vendorMapping = map[string]vendor{ 888 "AMDisbetter!": amd, 889 "AuthenticAMD": amd, 890 "CentaurHauls": via, 891 "GenuineIntel": intel, 892 "TransmetaCPU": transmeta, 893 "GenuineTMx86": transmeta, 894 "Geode by NSC": nsc, 895 "VIA VIA VIA ": via, 896 "KVMKVMKVMKVM": kvm, 897 "Microsoft Hv": msvm, 898 "VMwareVMware": vmware, 899 "XenVMMXenVMM": xenhvm, 900 "bhyve bhyve ": bhyve, 901 "HygonGenuine": hygon, 902 "Vortex86 SoC": sis, 903 "SiS SiS SiS ": sis, 904 "RiseRiseRise": sis, 905 "Genuine RDC": rdc, 906} 907 908func vendorID() (vendor, string) { 909 _, b, c, d := cpuid(0) 910 v := string(valAsString(b, d, c)) 911 vend, ok := vendorMapping[v] 912 if !ok { 913 return other, v 914 } 915 return vend, v 916} 917 918func cacheLine() int { 919 if maxFunctionID() < 0x1 { 920 return 0 921 } 922 923 _, ebx, _, _ := cpuid(1) 924 cache := (ebx & 0xff00) >> 5 // cflush size 925 if cache == 0 && maxExtendedFunction() >= 0x80000006 { 926 _, _, ecx, _ := cpuid(0x80000006) 927 cache = ecx & 0xff // cacheline size 928 } 929 // TODO: Read from Cache and TLB Information 930 return int(cache) 931} 932 933func (c *cpuInfo) cacheSize() { 934 c.cache.l1d = -1 935 c.cache.l1i = -1 936 c.cache.l2 = -1 937 c.cache.l3 = -1 938 vendor, _ := vendorID() 939 switch vendor { 940 case intel: 941 if maxFunctionID() < 4 { 942 return 943 } 944 for i := uint32(0); ; i++ { 945 eax, ebx, ecx, _ := cpuidex(4, i) 946 cacheType := eax & 15 947 if cacheType == 0 { 948 break 949 } 950 cacheLevel := (eax >> 5) & 7 951 coherency := int(ebx&0xfff) + 1 952 partitions := int((ebx>>12)&0x3ff) + 1 953 associativity := int((ebx>>22)&0x3ff) + 1 954 sets := int(ecx) + 1 955 size := associativity * partitions * coherency * sets 956 switch cacheLevel { 957 case 1: 958 if cacheType == 1 { 959 // 1 = Data Cache 960 c.cache.l1d = size 961 } else if cacheType == 2 { 962 // 2 = Instruction Cache 963 c.cache.l1i = size 964 } else { 965 if c.cache.l1d < 0 { 966 c.cache.l1i = size 967 } 968 if c.cache.l1i < 0 { 969 c.cache.l1i = size 970 } 971 } 972 case 2: 973 c.cache.l2 = size 974 case 3: 975 c.cache.l3 = size 976 } 977 } 978 case amd, hygon: 979 // Untested. 980 if maxExtendedFunction() < 0x80000005 { 981 return 982 } 983 _, _, ecx, edx := cpuid(0x80000005) 984 c.cache.l1d = int(((ecx >> 24) & 0xFF) * 1024) 985 c.cache.l1i = int(((edx >> 24) & 0xFF) * 1024) 986 987 if maxExtendedFunction() < 0x80000006 { 988 return 989 } 990 _, _, ecx, _ = cpuid(0x80000006) 991 c.cache.l2 = int(((ecx >> 16) & 0xFFFF) * 1024) 992 993 // CPUID Fn8000_001D_EAX_x[N:0] Cache Properties 994 if maxExtendedFunction() < 0x8000001D { 995 return 996 } 997 for i := uint32(0); i < math.MaxUint32; i++ { 998 eax, ebx, ecx, _ := cpuidex(0x8000001D, i) 999 1000 level := (eax >> 5) & 7 1001 cacheNumSets := ecx + 1 1002 cacheLineSize := 1 + (ebx & 2047) 1003 cachePhysPartitions := 1 + ((ebx >> 12) & 511) 1004 cacheNumWays := 1 + ((ebx >> 22) & 511) 1005 1006 typ := eax & 15 1007 size := int(cacheNumSets * cacheLineSize * cachePhysPartitions * cacheNumWays) 1008 if typ == 0 { 1009 return 1010 } 1011 1012 switch level { 1013 case 1: 1014 switch typ { 1015 case 1: 1016 // Data cache 1017 c.cache.l1d = size 1018 case 2: 1019 // Inst cache 1020 c.cache.l1i = size 1021 default: 1022 if c.cache.l1d < 0 { 1023 c.cache.l1i = size 1024 } 1025 if c.cache.l1i < 0 { 1026 c.cache.l1i = size 1027 } 1028 } 1029 case 2: 1030 c.cache.l2 = size 1031 case 3: 1032 c.cache.l3 = size 1033 } 1034 } 1035 } 1036 1037 return 1038} 1039 1040type sgxepcsection struct { 1041 baseaddress uint64 1042 epcsize uint64 1043} 1044 1045type sgxsupport struct { 1046 available bool 1047 launchcontrol bool 1048 sgx1supported bool 1049 sgx2supported bool 1050 maxenclavesizenot64 int64 1051 maxenclavesize64 int64 1052 epcsections []sgxepcsection 1053} 1054 1055func hasSGX(available, lc bool) (rval sgxsupport) { 1056 rval.available = available 1057 1058 if !available { 1059 return 1060 } 1061 1062 rval.launchcontrol = lc 1063 1064 a, _, _, d := cpuidex(0x12, 0) 1065 rval.sgx1supported = a&0x01 != 0 1066 rval.sgx2supported = a&0x02 != 0 1067 rval.maxenclavesizenot64 = 1 << (d & 0xFF) // pow 2 1068 rval.maxenclavesize64 = 1 << ((d >> 8) & 0xFF) // pow 2 1069 rval.epcsections = make([]sgxepcsection, 0) 1070 1071 for subleaf := uint32(2); subleaf < 2+8; subleaf++ { 1072 eax, ebx, ecx, edx := cpuidex(0x12, subleaf) 1073 leafType := eax & 0xf 1074 1075 if leafType == 0 { 1076 // Invalid subleaf, stop iterating 1077 break 1078 } else if leafType == 1 { 1079 // EPC Section subleaf 1080 baseAddress := uint64(eax&0xfffff000) + (uint64(ebx&0x000fffff) << 32) 1081 size := uint64(ecx&0xfffff000) + (uint64(edx&0x000fffff) << 32) 1082 1083 section := sgxepcsection{baseaddress: baseAddress, epcsize: size} 1084 rval.epcsections = append(rval.epcsections, section) 1085 } 1086 } 1087 1088 return 1089} 1090 1091func support() flags { 1092 mfi := maxFunctionID() 1093 vend, _ := vendorID() 1094 if mfi < 0x1 { 1095 return 0 1096 } 1097 rval := uint64(0) 1098 _, _, c, d := cpuid(1) 1099 if (d & (1 << 15)) != 0 { 1100 rval |= cmov 1101 } 1102 if (d & (1 << 23)) != 0 { 1103 rval |= mmx 1104 } 1105 if (d & (1 << 25)) != 0 { 1106 rval |= mmxext 1107 } 1108 if (d & (1 << 25)) != 0 { 1109 rval |= sse 1110 } 1111 if (d & (1 << 26)) != 0 { 1112 rval |= sse2 1113 } 1114 if (c & 1) != 0 { 1115 rval |= sse3 1116 } 1117 if (c & (1 << 5)) != 0 { 1118 rval |= vmx 1119 } 1120 if (c & 0x00000200) != 0 { 1121 rval |= ssse3 1122 } 1123 if (c & 0x00080000) != 0 { 1124 rval |= sse4 1125 } 1126 if (c & 0x00100000) != 0 { 1127 rval |= sse42 1128 } 1129 if (c & (1 << 25)) != 0 { 1130 rval |= aesni 1131 } 1132 if (c & (1 << 1)) != 0 { 1133 rval |= clmul 1134 } 1135 if c&(1<<23) != 0 { 1136 rval |= popcnt 1137 } 1138 if c&(1<<30) != 0 { 1139 rval |= rdrand 1140 } 1141 if c&(1<<29) != 0 { 1142 rval |= f16c 1143 } 1144 if c&(1<<13) != 0 { 1145 rval |= cx16 1146 } 1147 if vend == intel && (d&(1<<28)) != 0 && mfi >= 4 { 1148 if threadsPerCore() > 1 { 1149 rval |= htt 1150 } 1151 } 1152 if vend == amd && (d&(1<<28)) != 0 && mfi >= 4 { 1153 if threadsPerCore() > 1 { 1154 rval |= htt 1155 } 1156 } 1157 // Check XGETBV, OXSAVE and AVX bits 1158 if c&(1<<26) != 0 && c&(1<<27) != 0 && c&(1<<28) != 0 { 1159 // Check for OS support 1160 eax, _ := xgetbv(0) 1161 if (eax & 0x6) == 0x6 { 1162 rval |= avx 1163 if (c & 0x00001000) != 0 { 1164 rval |= fma3 1165 } 1166 } 1167 } 1168 1169 // Check AVX2, AVX2 requires OS support, but BMI1/2 don't. 1170 if mfi >= 7 { 1171 _, ebx, ecx, edx := cpuidex(7, 0) 1172 eax1, _, _, _ := cpuidex(7, 1) 1173 if (rval&avx) != 0 && (ebx&0x00000020) != 0 { 1174 rval |= avx2 1175 } 1176 if (ebx & 0x00000008) != 0 { 1177 rval |= bmi1 1178 if (ebx & 0x00000100) != 0 { 1179 rval |= bmi2 1180 } 1181 } 1182 if ebx&(1<<2) != 0 { 1183 rval |= sgx 1184 } 1185 if ebx&(1<<4) != 0 { 1186 rval |= hle 1187 } 1188 if ebx&(1<<9) != 0 { 1189 rval |= erms 1190 } 1191 if ebx&(1<<11) != 0 { 1192 rval |= rtm 1193 } 1194 if ebx&(1<<14) != 0 { 1195 rval |= mpx 1196 } 1197 if ebx&(1<<18) != 0 { 1198 rval |= rdseed 1199 } 1200 if ebx&(1<<19) != 0 { 1201 rval |= adx 1202 } 1203 if ebx&(1<<29) != 0 { 1204 rval |= sha 1205 } 1206 if edx&(1<<26) != 0 { 1207 rval |= ibpb 1208 } 1209 if ecx&(1<<30) != 0 { 1210 rval |= sgxlc 1211 } 1212 if edx&(1<<27) != 0 { 1213 rval |= stibp 1214 } 1215 1216 // Only detect AVX-512 features if XGETBV is supported 1217 if c&((1<<26)|(1<<27)) == (1<<26)|(1<<27) { 1218 // Check for OS support 1219 eax, _ := xgetbv(0) 1220 1221 // Verify that XCR0[7:5] = ‘111b’ (OPMASK state, upper 256-bit of ZMM0-ZMM15 and 1222 // ZMM16-ZMM31 state are enabled by OS) 1223 /// and that XCR0[2:1] = ‘11b’ (XMM state and YMM state are enabled by OS). 1224 if (eax>>5)&7 == 7 && (eax>>1)&3 == 3 { 1225 if ebx&(1<<16) != 0 { 1226 rval |= avx512f 1227 } 1228 if ebx&(1<<17) != 0 { 1229 rval |= avx512dq 1230 } 1231 if ebx&(1<<21) != 0 { 1232 rval |= avx512ifma 1233 } 1234 if ebx&(1<<26) != 0 { 1235 rval |= avx512pf 1236 } 1237 if ebx&(1<<27) != 0 { 1238 rval |= avx512er 1239 } 1240 if ebx&(1<<28) != 0 { 1241 rval |= avx512cd 1242 } 1243 if ebx&(1<<30) != 0 { 1244 rval |= avx512bw 1245 } 1246 if ebx&(1<<31) != 0 { 1247 rval |= avx512vl 1248 } 1249 // ecx 1250 if ecx&(1<<1) != 0 { 1251 rval |= avx512vbmi 1252 } 1253 if ecx&(1<<6) != 0 { 1254 rval |= avx512vbmi2 1255 } 1256 if ecx&(1<<8) != 0 { 1257 rval |= gfni 1258 } 1259 if ecx&(1<<9) != 0 { 1260 rval |= vaes 1261 } 1262 if ecx&(1<<10) != 0 { 1263 rval |= vpclmulqdq 1264 } 1265 if ecx&(1<<11) != 0 { 1266 rval |= avx512vnni 1267 } 1268 if ecx&(1<<12) != 0 { 1269 rval |= avx512bitalg 1270 } 1271 if ecx&(1<<14) != 0 { 1272 rval |= avx512vpopcntdq 1273 } 1274 // edx 1275 if edx&(1<<8) != 0 { 1276 rval |= avx512vp2intersect 1277 } 1278 // cpuid eax 07h,ecx=1 1279 if eax1&(1<<5) != 0 { 1280 rval |= avx512bf16 1281 } 1282 } 1283 } 1284 } 1285 1286 if maxExtendedFunction() >= 0x80000001 { 1287 _, _, c, d := cpuid(0x80000001) 1288 if (c & (1 << 5)) != 0 { 1289 rval |= lzcnt 1290 rval |= popcnt 1291 } 1292 if (d & (1 << 31)) != 0 { 1293 rval |= amd3dnow 1294 } 1295 if (d & (1 << 30)) != 0 { 1296 rval |= amd3dnowext 1297 } 1298 if (d & (1 << 23)) != 0 { 1299 rval |= mmx 1300 } 1301 if (d & (1 << 22)) != 0 { 1302 rval |= mmxext 1303 } 1304 if (c & (1 << 6)) != 0 { 1305 rval |= sse4a 1306 } 1307 if d&(1<<20) != 0 { 1308 rval |= nx 1309 } 1310 if d&(1<<27) != 0 { 1311 rval |= rdtscp 1312 } 1313 1314 /* Allow for selectively disabling SSE2 functions on AMD processors 1315 with SSE2 support but not SSE4a. This includes Athlon64, some 1316 Opteron, and some Sempron processors. MMX, SSE, or 3DNow! are faster 1317 than SSE2 often enough to utilize this special-case flag. 1318 AV_CPU_FLAG_SSE2 and AV_CPU_FLAG_SSE2SLOW are both set in this case 1319 so that SSE2 is used unless explicitly disabled by checking 1320 AV_CPU_FLAG_SSE2SLOW. */ 1321 if vend != intel && 1322 rval&sse2 != 0 && (c&0x00000040) == 0 { 1323 rval |= sse2slow 1324 } 1325 1326 /* XOP and FMA4 use the AVX instruction coding scheme, so they can't be 1327 * used unless the OS has AVX support. */ 1328 if (rval & avx) != 0 { 1329 if (c & 0x00000800) != 0 { 1330 rval |= xop 1331 } 1332 if (c & 0x00010000) != 0 { 1333 rval |= fma4 1334 } 1335 } 1336 1337 if vend == intel { 1338 family, model := familyModel() 1339 if family == 6 && (model == 9 || model == 13 || model == 14) { 1340 /* 6/9 (pentium-m "banias"), 6/13 (pentium-m "dothan"), and 1341 * 6/14 (core1 "yonah") theoretically support sse2, but it's 1342 * usually slower than mmx. */ 1343 if (rval & sse2) != 0 { 1344 rval |= sse2slow 1345 } 1346 if (rval & sse3) != 0 { 1347 rval |= sse3slow 1348 } 1349 } 1350 /* The Atom processor has SSSE3 support, which is useful in many cases, 1351 * but sometimes the SSSE3 version is slower than the SSE2 equivalent 1352 * on the Atom, but is generally faster on other processors supporting 1353 * SSSE3. This flag allows for selectively disabling certain SSSE3 1354 * functions on the Atom. */ 1355 if family == 6 && model == 28 { 1356 rval |= atom 1357 } 1358 } 1359 } 1360 return flags(rval) 1361} 1362 1363func valAsString(values ...uint32) []byte { 1364 r := make([]byte, 4*len(values)) 1365 for i, v := range values { 1366 dst := r[i*4:] 1367 dst[0] = byte(v & 0xff) 1368 dst[1] = byte((v >> 8) & 0xff) 1369 dst[2] = byte((v >> 16) & 0xff) 1370 dst[3] = byte((v >> 24) & 0xff) 1371 switch { 1372 case dst[0] == 0: 1373 return r[:i*4] 1374 case dst[1] == 0: 1375 return r[:i*4+1] 1376 case dst[2] == 0: 1377 return r[:i*4+2] 1378 case dst[3] == 0: 1379 return r[:i*4+3] 1380 } 1381 } 1382 return r 1383} 1384 1385// Single-precision and double-precision floating point 1386func (c cpuInfo) armfp() bool { 1387 return c.arm&fp != 0 1388} 1389 1390// Advanced SIMD 1391func (c cpuInfo) armasimd() bool { 1392 return c.arm&asimd != 0 1393} 1394 1395// Generic timer 1396func (c cpuInfo) armevtstrm() bool { 1397 return c.arm&evtstrm != 0 1398} 1399 1400// AES instructions 1401func (c cpuInfo) armaes() bool { 1402 return c.arm&aes != 0 1403} 1404 1405// Polynomial Multiply instructions (PMULL/PMULL2) 1406func (c cpuInfo) armpmull() bool { 1407 return c.arm&pmull != 0 1408} 1409 1410// SHA-1 instructions (SHA1C, etc) 1411func (c cpuInfo) armsha1() bool { 1412 return c.arm&sha1 != 0 1413} 1414 1415// SHA-2 instructions (SHA256H, etc) 1416func (c cpuInfo) armsha2() bool { 1417 return c.arm&sha2 != 0 1418} 1419 1420// CRC32/CRC32C instructions 1421func (c cpuInfo) armcrc32() bool { 1422 return c.arm&crc32 != 0 1423} 1424 1425// Large System Extensions (LSE) 1426func (c cpuInfo) armatomics() bool { 1427 return c.arm&atomics != 0 1428} 1429 1430// Half-precision floating point 1431func (c cpuInfo) armfphp() bool { 1432 return c.arm&fphp != 0 1433} 1434 1435// Advanced SIMD half-precision floating point 1436func (c cpuInfo) armasimdhp() bool { 1437 return c.arm&asimdhp != 0 1438} 1439 1440// Rounding Double Multiply Accumulate/Subtract (SQRDMLAH/SQRDMLSH) 1441func (c cpuInfo) armasimdrdm() bool { 1442 return c.arm&asimdrdm != 0 1443} 1444 1445// Javascript-style double->int convert (FJCVTZS) 1446func (c cpuInfo) armjscvt() bool { 1447 return c.arm&jscvt != 0 1448} 1449 1450// Floatin point complex number addition and multiplication 1451func (c cpuInfo) armfcma() bool { 1452 return c.arm&fcma != 0 1453} 1454 1455// Weaker release consistency (LDAPR, etc) 1456func (c cpuInfo) armlrcpc() bool { 1457 return c.arm&lrcpc != 0 1458} 1459 1460// Data cache clean to Point of Persistence (DC CVAP) 1461func (c cpuInfo) armdcpop() bool { 1462 return c.arm&dcpop != 0 1463} 1464 1465// SHA-3 instructions (EOR3, RAXI, XAR, BCAX) 1466func (c cpuInfo) armsha3() bool { 1467 return c.arm&sha3 != 0 1468} 1469 1470// SM3 instructions 1471func (c cpuInfo) armsm3() bool { 1472 return c.arm&sm3 != 0 1473} 1474 1475// SM4 instructions 1476func (c cpuInfo) armsm4() bool { 1477 return c.arm&sm4 != 0 1478} 1479 1480// SIMD Dot Product 1481func (c cpuInfo) armasimddp() bool { 1482 return c.arm&asimddp != 0 1483} 1484 1485// SHA512 instructions 1486func (c cpuInfo) armsha512() bool { 1487 return c.arm&sha512 != 0 1488} 1489 1490// Scalable Vector Extension 1491func (c cpuInfo) armsve() bool { 1492 return c.arm&sve != 0 1493} 1494 1495// Generic Pointer Authentication 1496func (c cpuInfo) armgpa() bool { 1497 return c.arm&gpa != 0 1498} 1499