blob: 026f0cd88e1a64d53dc52238f176f59e0182bd90 [file] [log] [blame]
// 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
}