github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/src/runtime/cpuflags_amd64.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime 6 7 var vendorStringBytes [12]byte 8 var maxInputValue uint32 9 var featureFlags uint32 10 var processorVersionInfo uint32 11 12 var useRepMovs = true 13 14 func hasFeature(feature uint32) bool { 15 return (featureFlags & feature) != 0 16 } 17 18 func cpuid_low(arg1, arg2 uint32) (eax, ebx, ecx, edx uint32) // implemented in cpuidlow_amd64.s 19 func xgetbv_low(arg1 uint32) (eax, edx uint32) // implemented in cpuidlow_amd64.s 20 21 func init() { 22 const cfOSXSAVE uint32 = 1 << 27 23 const cfAVX uint32 = 1 << 28 24 25 leaf0() 26 leaf1() 27 28 enabledAVX := false 29 // Let's check if OS has set CR4.OSXSAVE[bit 18] 30 // to enable XGETBV instruction. 31 if hasFeature(cfOSXSAVE) { 32 eax, _ := xgetbv_low(0) 33 // Let's check that XCR0[2:1] = ‘11b’ 34 // i.e. XMM state and YMM state are enabled by OS. 35 enabledAVX = (eax & 0x6) == 0x6 36 } 37 38 isIntelBridgeFamily := (processorVersionInfo == 0x206A0 || 39 processorVersionInfo == 0x206D0 || 40 processorVersionInfo == 0x306A0 || 41 processorVersionInfo == 0x306E0) && 42 isIntel() 43 44 useRepMovs = !(hasFeature(cfAVX) && enabledAVX) || isIntelBridgeFamily 45 } 46 47 func leaf0() { 48 eax, ebx, ecx, edx := cpuid_low(0, 0) 49 maxInputValue = eax 50 int32ToBytes(ebx, vendorStringBytes[0:4]) 51 int32ToBytes(edx, vendorStringBytes[4:8]) 52 int32ToBytes(ecx, vendorStringBytes[8:12]) 53 } 54 55 func leaf1() { 56 if maxInputValue < 1 { 57 return 58 } 59 eax, _, ecx, _ := cpuid_low(1, 0) 60 // Let's remove stepping and reserved fields 61 processorVersionInfo = eax & 0x0FFF3FF0 62 featureFlags = ecx 63 } 64 65 func int32ToBytes(arg uint32, buffer []byte) { 66 buffer[3] = byte(arg >> 24) 67 buffer[2] = byte(arg >> 16) 68 buffer[1] = byte(arg >> 8) 69 buffer[0] = byte(arg) 70 } 71 72 func isIntel() bool { 73 intelSignature := [12]byte{'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l'} 74 return vendorStringBytes == intelSignature 75 }