...
Run Format

Source file src/runtime/cpuflags_amd64.go

  // Copyright 2015 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package runtime
  
  var vendorStringBytes [12]byte
  var maxInputValue uint32
  var featureFlags uint32
  var processorVersionInfo uint32
  
  var useRepMovs = true
  
  func hasFeature(feature uint32) bool {
  	return (featureFlags & feature) != 0
  }
  
  func cpuid_low(arg1, arg2 uint32) (eax, ebx, ecx, edx uint32) // implemented in cpuidlow_amd64.s
  func xgetbv_low(arg1 uint32) (eax, edx uint32)                // implemented in cpuidlow_amd64.s
  
  func init() {
  	const cfOSXSAVE uint32 = 1 << 27
  	const cfAVX uint32 = 1 << 28
  
  	leaf0()
  	leaf1()
  
  	enabledAVX := false
  	// Let's check if OS has set CR4.OSXSAVE[bit 18]
  	// to enable XGETBV instruction.
  	if hasFeature(cfOSXSAVE) {
  		eax, _ := xgetbv_low(0)
  		// Let's check that XCR0[2:1] = β€˜11b’
  		// i.e. XMM state and YMM state are enabled by OS.
  		enabledAVX = (eax & 0x6) == 0x6
  	}
  
  	isIntelBridgeFamily := (processorVersionInfo == 0x206A0 ||
  		processorVersionInfo == 0x206D0 ||
  		processorVersionInfo == 0x306A0 ||
  		processorVersionInfo == 0x306E0) &&
  		isIntel()
  
  	useRepMovs = !(hasFeature(cfAVX) && enabledAVX) || isIntelBridgeFamily
  }
  
  func leaf0() {
  	eax, ebx, ecx, edx := cpuid_low(0, 0)
  	maxInputValue = eax
  	int32ToBytes(ebx, vendorStringBytes[0:4])
  	int32ToBytes(edx, vendorStringBytes[4:8])
  	int32ToBytes(ecx, vendorStringBytes[8:12])
  }
  
  func leaf1() {
  	if maxInputValue < 1 {
  		return
  	}
  	eax, _, ecx, _ := cpuid_low(1, 0)
  	// Let's remove stepping and reserved fields
  	processorVersionInfo = eax & 0x0FFF3FF0
  	featureFlags = ecx
  }
  
  func int32ToBytes(arg uint32, buffer []byte) {
  	buffer[3] = byte(arg >> 24)
  	buffer[2] = byte(arg >> 16)
  	buffer[1] = byte(arg >> 8)
  	buffer[0] = byte(arg)
  }
  
  func isIntel() bool {
  	intelSignature := [12]byte{'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l'}
  	return vendorStringBytes == intelSignature
  }
  

View as plain text