cosmopolitan/libc/nexgen32e/kcpuids.S

89 lines
3.5 KiB
ArmAsm

/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify │
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License. │
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of │
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software │
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "ape/lib/pc.h"
#include "libc/dce.h"
#include "libc/macros.h"
#include "libc/nexgen32e/kcpuids.h"
#include "libc/nexgen32e/x86feature.h"
/ Globally precomputed CPUID.
/
/ This module lets us check CPUID in 0.06ns rather than 51.00ns.
/ If every piece of native software linked this module, then the
/ world would be a much better place; since all the alternatives
/ are quite toilsome.
/
/ @see www.felixcloutier.com/x86/cpuid
.initbss 201,_init_kCpuids
kCpuids:.long 0,0,0,0 # EAX=0 (Basic Processor Info)
.long 0,0,0,0 # EAX=1 (Processor Info)
.long 0,0,0,0 # EAX=2
.long 0,0,0,0 # EAX=7 (Extended Features)
.long 0,0,0,0 # EAX=0x80000001 (NexGen32e)
.long 0,0,0,0 # EAX=0x80000007 (APM)
.long 0,0,0,0 # EAX=16h (CPU Frequency)
.endobj kCpuids,globl
.previous
.init.start 201,_init_kCpuids
push %rbx
push $0
push $0x16
push $0xffffffff80000007
push $0xffffffff80000001
push $7
push $2
push $1
mov %rdi,%r8
xor %eax,%eax
1: xor %ecx,%ecx
cpuid
stosl
xchg %eax,%ebx
stosl
xchg %eax,%ecx
stosl
xchg %eax,%edx
stosl
2: pop %rax
test %eax,%eax # EAX = stacklist->pop()
jz 3f # EAX 0 (EOL sentinel)
cmp KCPUIDS(0H,EAX)(%r8),%al # EAX CPUID.0 max leaf
jbe 1b # CPUID too new to probe
add $4*4,%rdi
jmp 2b
3: nop
#if !X86_NEED(AVX2)
testb X86_HAVE(AVX)(%r8)
jz 5f
testb X86_HAVE(OSXSAVE)(%r8)
jz 4f
xor %ecx,%ecx
xgetbv
and $XCR0_SSE|XCR0_AVX,%eax
cmp $XCR0_SSE|XCR0_AVX,%eax
je 5f
4: btr $X86_BIT(AVX),X86_WORD(AVX)(%r8)
btr $X86_BIT(AVX2),X86_WORD(AVX2)(%r8)
#endif
5: pop %rbx
.init.end 201,_init_kCpuids
.source __FILE__