mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 05:59:28 +02:00
+ AVXSupport function to detect if the CPU and OS support AVX
git-svn-id: trunk@22641 -
This commit is contained in:
parent
91f1a8736c
commit
c57f463ede
@ -13,6 +13,7 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
{$mode objfpc}
|
||||
unit cpu;
|
||||
interface
|
||||
|
||||
@ -25,13 +26,16 @@ unit cpu;
|
||||
{ returns the contents of the cr0 register }
|
||||
function cr0 : longint;
|
||||
|
||||
function AVXSupport: boolean;inline;
|
||||
|
||||
var
|
||||
is_sse3_cpu : boolean = false;
|
||||
|
||||
implementation
|
||||
|
||||
{$ASMMODE INTEL}
|
||||
|
||||
var
|
||||
_AVXSupport : boolean;
|
||||
|
||||
function cpuid_support : boolean;assembler;
|
||||
{
|
||||
@ -76,10 +80,19 @@ unit cpu;
|
||||
|
||||
|
||||
{$ASMMODE ATT}
|
||||
function sse3_support : boolean;
|
||||
function XGETBV(i : dword) : int64;assembler;
|
||||
asm
|
||||
movl %eax,%ecx
|
||||
// older FPCs don't know the xgetbv opcode
|
||||
.byte 0x0f,0x01,0xd0
|
||||
end;
|
||||
|
||||
|
||||
procedure SetupSupport;
|
||||
var
|
||||
_ecx : longint;
|
||||
begin
|
||||
is_sse3_cpu:=false;
|
||||
if cpuid_support then
|
||||
begin
|
||||
asm
|
||||
@ -89,13 +102,23 @@ unit cpu;
|
||||
movl %ecx,_ecx
|
||||
popl %ebx
|
||||
end;
|
||||
sse3_support:=(_ecx and $1)<>0;
|
||||
end
|
||||
else
|
||||
{ a cpu with without cpuid instruction supports never sse3 }
|
||||
sse3_support:=false;
|
||||
is_sse3_cpu:=(_ecx and $1)<>0;
|
||||
_AVXSupport:=
|
||||
{ XGETBV suspport? }
|
||||
((_ecx and $08000000)<>0) and
|
||||
{ xmm and ymm state enabled? }
|
||||
((XGETBV(0) and %110)=%110) and
|
||||
{ avx supported? }
|
||||
((_ecx and $10000000)<>0);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function AVXSupport: boolean;inline;
|
||||
begin
|
||||
result:=_AVXSupport;
|
||||
end;
|
||||
|
||||
begin
|
||||
is_sse3_cpu:=sse3_support;
|
||||
SetupSupport;
|
||||
end.
|
||||
|
@ -30,6 +30,7 @@ unit cpu;
|
||||
|
||||
function InterlockedCompareExchange128Support : boolean;inline;
|
||||
function AESSupport : boolean;inline;
|
||||
function AVXSupport : boolean;inline;
|
||||
|
||||
var
|
||||
is_sse3_cpu : boolean = false;
|
||||
@ -40,6 +41,7 @@ unit cpu;
|
||||
|
||||
var
|
||||
_AESSupport,
|
||||
_AVXSupport,
|
||||
_InterlockedCompareExchange128Support : boolean;
|
||||
|
||||
function InterlockedCompareExchange128Support : boolean;inline;
|
||||
@ -52,6 +54,10 @@ unit cpu;
|
||||
result:=_AESSupport;
|
||||
end;
|
||||
|
||||
function AVXSupport: boolean;
|
||||
begin
|
||||
result:=_AVXSupport;
|
||||
end;
|
||||
|
||||
function InterlockedCompareExchange128(var Target: Int128Rec; NewValue: Int128Rec; Comperand: Int128Rec): Int128Rec; assembler;
|
||||
{
|
||||
@ -119,6 +125,19 @@ unit cpu;
|
||||
{$endif win64}
|
||||
|
||||
|
||||
function XGETBV(i : dword) : int64;assembler;
|
||||
asm
|
||||
{$ifndef win64}
|
||||
movq %rdi,%rcx
|
||||
{$endif win64}
|
||||
// older FPCs don't know the xgetbv opcode
|
||||
.byte 0x0f,0x01,0xd0
|
||||
andl $0xffffffff,%eax
|
||||
shll $32,%rdx
|
||||
orq %rdx,%rax
|
||||
end;
|
||||
|
||||
|
||||
procedure SetupSupport;
|
||||
var
|
||||
_ecx : longint;
|
||||
@ -132,6 +151,15 @@ unit cpu;
|
||||
end;
|
||||
_InterlockedCompareExchange128Support:=(_ecx and $2000)<>0;
|
||||
_AESSupport:=(_ecx and $2000000)<>0;
|
||||
|
||||
_AVXSupport:=
|
||||
{ XGETBV suspport? }
|
||||
((_ecx and $08000000)<>0) and
|
||||
{ xmm and ymm state enabled? }
|
||||
((XGETBV(0) and %110)=%110) and
|
||||
{ avx supported? }
|
||||
((_ecx and $10000000)<>0);
|
||||
|
||||
is_sse3_cpu:=(_ecx and $1)<>0;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user