+ AVXSupport function to detect if the CPU and OS support AVX

git-svn-id: trunk@22641 -
This commit is contained in:
florian 2012-10-14 14:04:27 +00:00
parent 91f1a8736c
commit c57f463ede
2 changed files with 59 additions and 8 deletions

View File

@ -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.

View File

@ -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;