cpu_amd64.s raw

   1  // Copyright (c) 2024 The Decred developers
   2  // Use of this source code is governed by an ISC
   3  // license that can be found in the LICENSE file.
   4  //
   5  // Feature detection originally written by Dave Collins Feb 2019.
   6  
   7  //go:build !purego
   8  
   9  #include "textflag.h"
  10  
  11  // func supportsCPUID() bool
  12  TEXT ·supportsCPUID(SB), $8-4
  13  	// Per the Intel 64 and IA-32 Architectures Software Developer's Manual,
  14  	// CPUID is supported if bit 21 of the EFLAGS register can be modified.
  15  	//
  16  	// To that end, this works as follows:
  17  	//
  18  	// 1. Get the current value of EFLAGS by pushing it and popping it into AX.
  19  	// 2. Make a copy into BX for later comparison.
  20  	// 3. Toggle bit 21 (the EFLAGS ID bit) of AX.
  21  	// 4. Put the modified value back into EFLAGS by pushing it and popping it
  22  	//    into EFLAGS.  The CPU will either update bit 21 of the EFLAGS with the
  23  	//    modified value when it supports CPUID or leave it unmodified when it
  24  	//    does not.
  25  	// 5. Get the potentially modified value of EFLAGS by pushing it and popping
  26  	//    it into AX.
  27  	// 6. Compare the original and potentially modified value (aka AX vs BX)
  28  	// 7. CPUID is supported when they do not match since bit 21 was able to be
  29  	//    modified.
  30  	PUSHFQ
  31  	POPQ AX
  32  	MOVQ AX, BX
  33  	XORQ $0x200000, AX
  34  	PUSHQ AX
  35  	POPFQ
  36  	PUSHFQ
  37  	POPQ AX
  38  	CMPQ AX, BX
  39  	JE nocpuid
  40  	MOVB $1, ret+0(FP)
  41  	RET
  42  nocpuid:
  43  	MOVB $0, ret+0(FP)
  44  	RET
  45  
  46  // func cpuid(eaxIn, ecxIn uint32) (eax, ebx, ecx, edx uint32)
  47  TEXT ·cpuid(SB), NOSPLIT, $0-24
  48  	MOVL eaxIn+0(FP), AX
  49  	MOVL ecxIn+4(FP), CX
  50  	CPUID
  51  	MOVL AX, eax+8(FP)
  52  	MOVL BX, ebx+12(FP)
  53  	MOVL CX, ecx+16(FP)
  54  	MOVL DX, edx+20(FP)
  55  	RET
  56  
  57  // func xgetbv() (eax uint32)
  58  TEXT ·xgetbv(SB), NOSPLIT, $0-4
  59  	MOVL $0, CX
  60  	XGETBV
  61  	MOVL AX, eax+0(FP)
  62  	RET
  63