github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/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  }