mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 09:09:19 +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.
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
**********************************************************************}
|
**********************************************************************}
|
||||||
|
{$mode objfpc}
|
||||||
unit cpu;
|
unit cpu;
|
||||||
interface
|
interface
|
||||||
|
|
||||||
@ -25,13 +26,16 @@ unit cpu;
|
|||||||
{ returns the contents of the cr0 register }
|
{ returns the contents of the cr0 register }
|
||||||
function cr0 : longint;
|
function cr0 : longint;
|
||||||
|
|
||||||
|
function AVXSupport: boolean;inline;
|
||||||
|
|
||||||
var
|
var
|
||||||
is_sse3_cpu : boolean = false;
|
is_sse3_cpu : boolean = false;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
{$ASMMODE INTEL}
|
{$ASMMODE INTEL}
|
||||||
|
var
|
||||||
|
_AVXSupport : boolean;
|
||||||
|
|
||||||
function cpuid_support : boolean;assembler;
|
function cpuid_support : boolean;assembler;
|
||||||
{
|
{
|
||||||
@ -76,10 +80,19 @@ unit cpu;
|
|||||||
|
|
||||||
|
|
||||||
{$ASMMODE ATT}
|
{$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
|
var
|
||||||
_ecx : longint;
|
_ecx : longint;
|
||||||
begin
|
begin
|
||||||
|
is_sse3_cpu:=false;
|
||||||
if cpuid_support then
|
if cpuid_support then
|
||||||
begin
|
begin
|
||||||
asm
|
asm
|
||||||
@ -89,13 +102,23 @@ unit cpu;
|
|||||||
movl %ecx,_ecx
|
movl %ecx,_ecx
|
||||||
popl %ebx
|
popl %ebx
|
||||||
end;
|
end;
|
||||||
sse3_support:=(_ecx and $1)<>0;
|
is_sse3_cpu:=(_ecx and $1)<>0;
|
||||||
end
|
_AVXSupport:=
|
||||||
else
|
{ XGETBV suspport? }
|
||||||
{ a cpu with without cpuid instruction supports never sse3 }
|
((_ecx and $08000000)<>0) and
|
||||||
sse3_support:=false;
|
{ 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;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
is_sse3_cpu:=sse3_support;
|
SetupSupport;
|
||||||
end.
|
end.
|
||||||
|
@ -30,6 +30,7 @@ unit cpu;
|
|||||||
|
|
||||||
function InterlockedCompareExchange128Support : boolean;inline;
|
function InterlockedCompareExchange128Support : boolean;inline;
|
||||||
function AESSupport : boolean;inline;
|
function AESSupport : boolean;inline;
|
||||||
|
function AVXSupport : boolean;inline;
|
||||||
|
|
||||||
var
|
var
|
||||||
is_sse3_cpu : boolean = false;
|
is_sse3_cpu : boolean = false;
|
||||||
@ -40,6 +41,7 @@ unit cpu;
|
|||||||
|
|
||||||
var
|
var
|
||||||
_AESSupport,
|
_AESSupport,
|
||||||
|
_AVXSupport,
|
||||||
_InterlockedCompareExchange128Support : boolean;
|
_InterlockedCompareExchange128Support : boolean;
|
||||||
|
|
||||||
function InterlockedCompareExchange128Support : boolean;inline;
|
function InterlockedCompareExchange128Support : boolean;inline;
|
||||||
@ -52,6 +54,10 @@ unit cpu;
|
|||||||
result:=_AESSupport;
|
result:=_AESSupport;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function AVXSupport: boolean;
|
||||||
|
begin
|
||||||
|
result:=_AVXSupport;
|
||||||
|
end;
|
||||||
|
|
||||||
function InterlockedCompareExchange128(var Target: Int128Rec; NewValue: Int128Rec; Comperand: Int128Rec): Int128Rec; assembler;
|
function InterlockedCompareExchange128(var Target: Int128Rec; NewValue: Int128Rec; Comperand: Int128Rec): Int128Rec; assembler;
|
||||||
{
|
{
|
||||||
@ -119,6 +125,19 @@ unit cpu;
|
|||||||
{$endif win64}
|
{$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;
|
procedure SetupSupport;
|
||||||
var
|
var
|
||||||
_ecx : longint;
|
_ecx : longint;
|
||||||
@ -132,6 +151,15 @@ unit cpu;
|
|||||||
end;
|
end;
|
||||||
_InterlockedCompareExchange128Support:=(_ecx and $2000)<>0;
|
_InterlockedCompareExchange128Support:=(_ecx and $2000)<>0;
|
||||||
_AESSupport:=(_ecx and $2000000)<>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;
|
is_sse3_cpu:=(_ecx and $1)<>0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user