瀏覽代碼

+ AVX512*Support functions
* call cpuid with eax=7 only if it is supported by the CPU

git-svn-id: trunk@49601 -

florian 4 年之前
父節點
當前提交
6c0b79c258
共有 2 個文件被更改,包括 187 次插入24 次删除
  1. 95 13
      rtl/i386/cpu.pp
  2. 92 11
      rtl/x86_64/cpu.pp

+ 95 - 13
rtl/i386/cpu.pp

@@ -35,6 +35,14 @@ unit cpu;
     function AESSupport : boolean;inline;
     function AESSupport : boolean;inline;
     function AVXSupport: boolean;inline;
     function AVXSupport: boolean;inline;
     function AVX2Support: boolean;inline;
     function AVX2Support: boolean;inline;
+    function AVX512FSupport: boolean;inline;    
+    function AVX512DQSupport: boolean;inline;    
+    function AVX512IFMASupport: boolean;inline;    
+    function AVX512PFSupport: boolean;inline;    
+    function AVX512ERSupport: boolean;inline;    
+    function AVX512CDSupport: boolean;inline;    
+    function AVX512BWSupport: boolean;inline;    
+    function AVX512VLSupport: boolean;inline;    
     function FMASupport: boolean;inline;
     function FMASupport: boolean;inline;
     function POPCNTSupport: boolean;inline;
     function POPCNTSupport: boolean;inline;
     function SSE41Support: boolean;inline;
     function SSE41Support: boolean;inline;
@@ -57,6 +65,14 @@ unit cpu;
     var
     var
       _AVXSupport,
       _AVXSupport,
       _AVX2Support,
       _AVX2Support,
+      _AVX512FSupport,
+      _AVX512DQSupport,
+      _AVX512IFMASupport,
+      _AVX512PFSupport,
+      _AVX512ERSupport,
+      _AVX512CDSupport,
+      _AVX512BWSupport,
+      _AVX512VLSupport,
       _AESSupport,
       _AESSupport,
       _FMASupport,
       _FMASupport,
       _POPCNTSupport,
       _POPCNTSupport,
@@ -167,11 +183,18 @@ unit cpu;
 
 
     procedure SetupSupport;
     procedure SetupSupport;
       var
       var
-         _ecx,_ebx : longint;
+         _ecx,_ebx,maxcpuidvalue : longint;
       begin
       begin
         is_sse3_cpu:=false;
         is_sse3_cpu:=false;
          if cpuid_support then
          if cpuid_support then
            begin
            begin
+              asm
+                 pushl %ebx
+                 movl $0,%eax
+                 cpuid
+                 movl %eax,maxcpuidvalue
+                 popl %ebx
+              end;
               asm
               asm
                  pushl %ebx
                  pushl %ebx
                  movl $1,%eax
                  movl $1,%eax
@@ -199,18 +222,29 @@ unit cpu;
 
 
               _FMASupport:=_AVXSupport and ((_ecx and $1000)<>0);
               _FMASupport:=_AVXSupport and ((_ecx and $1000)<>0);
 
 
-              asm
-                 pushl %ebx
-                 movl $7,%eax
-                 movl $0,%ecx
-                 cpuid
-                 movl %ebx,_ebx
-                 popl %ebx
-              end;
-              _AVX2Support:=_AVXSupport and ((_ebx and $20)<>0);
-              _BMI1Support:=(_ebx and $8)<>0;
-              _BMI2Support:=(_ebx and $100)<>0;
-              _RTMSupport:=((_ebx and $800)<>0);
+              if maxcpuidvalue>=7 then
+                begin
+                  asm
+                    pushl %ebx
+                    movl $7,%eax
+                    movl $0,%ecx
+                    cpuid
+                    movl %ebx,_ebx
+                    popl %ebx
+                  end;
+                  _AVX2Support:=_AVXSupport and ((_ebx and $20)<>0);
+                  _AVX512FSupport:=(_ebx and $10000)<>0;
+                  _AVX512DQSupport:=(_ebx and $20000)<>0;
+                  _AVX512IFMASupport:=(_ebx and $200000)<>0;
+                  _AVX512PFSupport:=(_ebx and $4000000)<>0;
+                  _AVX512ERSupport:=(_ebx and $8000000)<>0;
+                  _AVX512CDSupport:=(_ebx and $10000000)<>0;
+                  _AVX512BWSupport:=(_ebx and $40000000)<>0;
+                  _AVX512VLSupport:=(_ebx and $80000000)<>0;
+                  _BMI1Support:=(_ebx and $8)<>0;
+                  _BMI2Support:=(_ebx and $100)<>0;
+                  _RTMSupport:=((_ebx and $800)<>0);
+                end;
            end;
            end;
       end;
       end;
 
 
@@ -241,6 +275,54 @@ unit cpu;
       end;
       end;
 
 
 
 
+    function AVX512FSupport: boolean;inline;
+      begin
+        result:=_AVX512FSupport;
+      end;
+
+
+    function AVX512DQSupport: boolean;inline;
+      begin
+        result:=_AVX512DQSupport;
+      end;
+
+
+    function AVX512IFMASupport: boolean;inline;    
+      begin
+        result:=_AVX512IFMASupport;
+      end;
+
+
+    function AVX512PFSupport: boolean;inline;    
+      begin
+        result:=_AVX512PFSupport;
+      end;
+
+
+    function AVX512ERSupport: boolean;inline;    
+      begin
+        result:=_AVX512ERSupport;
+      end;
+
+
+    function AVX512CDSupport: boolean;inline;    
+      begin
+        result:=_AVX512CDSupport;
+      end;
+
+
+    function AVX512BWSupport: boolean;inline;    
+      begin
+        result:=_AVX512BWSupport;
+      end;
+
+
+    function AVX512VLSupport: boolean;inline;    
+      begin
+        result:=_AVX512VLSupport;
+      end;
+
+
     function FMASupport: boolean;inline;
     function FMASupport: boolean;inline;
       begin
       begin
         result:=_FMASupport;
         result:=_FMASupport;

+ 92 - 11
rtl/x86_64/cpu.pp

@@ -32,6 +32,14 @@ unit cpu;
     function AESSupport : boolean;inline;
     function AESSupport : boolean;inline;
     function AVXSupport : boolean;inline;
     function AVXSupport : boolean;inline;
     function AVX2Support: boolean;inline;
     function AVX2Support: boolean;inline;
+    function AVX512FSupport: boolean;inline;    
+    function AVX512DQSupport: boolean;inline;    
+    function AVX512IFMASupport: boolean;inline;    
+    function AVX512PFSupport: boolean;inline;    
+    function AVX512ERSupport: boolean;inline;    
+    function AVX512CDSupport: boolean;inline;    
+    function AVX512BWSupport: boolean;inline;    
+    function AVX512VLSupport: boolean;inline;    
     function FMASupport: boolean;inline;
     function FMASupport: boolean;inline;
     function POPCNTSupport: boolean;inline;
     function POPCNTSupport: boolean;inline;
     function SSE41Support: boolean;inline;
     function SSE41Support: boolean;inline;
@@ -57,6 +65,14 @@ unit cpu;
       _AVXSupport,
       _AVXSupport,
       _InterlockedCompareExchange128Support,
       _InterlockedCompareExchange128Support,
       _AVX2Support,
       _AVX2Support,
+      _AVX512FSupport,
+      _AVX512DQSupport,
+      _AVX512IFMASupport,
+      _AVX512PFSupport,
+      _AVX512ERSupport,
+      _AVX512CDSupport,
+      _AVX512BWSupport,
+      _AVX512VLSupport,
       _FMASupport,
       _FMASupport,
       _POPCNTSupport,
       _POPCNTSupport,
       _SSE41Support,
       _SSE41Support,
@@ -150,8 +166,13 @@ unit cpu;
     procedure SetupSupport;
     procedure SetupSupport;
       var
       var
         _ecx,
         _ecx,
-        _ebx : longint;
+        _ebx,maxcpuidvalue : longint;
       begin
       begin
+        asm
+           movl $0x0,%eax
+           cpuid
+           movl %eax,maxcpuidvalue
+        end ['rax','rbx','rcx','rdx'];
         asm
         asm
            movl $0x00000001,%eax
            movl $0x00000001,%eax
            cpuid
            cpuid
@@ -178,16 +199,28 @@ unit cpu;
 
 
         _FMASupport:=_AVXSupport and ((_ecx and $1000)<>0);
         _FMASupport:=_AVXSupport and ((_ecx and $1000)<>0);
 
 
-        asm
-           movl $7,%eax
-           movl $0,%ecx
-           cpuid
-           movl %ebx,_ebx
-        end ['rax','rbx','rcx','rdx'];
-        _AVX2Support:=_AVXSupport and ((_ebx and $20)<>0);
-        _BMI1Support:=(_ebx and $8)<>0;
-        _BMI2Support:=(_ebx and $100)<>0;
-        _RTMSupport:=(_ebx and $800)<>0;
+        { very early x86-64 CPUs might not support eax=7 }
+        if maxcpuidvalue>=7 then
+          begin
+            asm
+              movl $7,%eax
+              movl $0,%ecx
+              cpuid
+              movl %ebx,_ebx
+            end ['rax','rbx','rcx','rdx'];
+            _AVX2Support:=_AVXSupport and ((_ebx and $20)<>0);
+            _AVX512FSupport:=(_ebx and $10000)<>0;
+            _AVX512DQSupport:=(_ebx and $20000)<>0;
+            _AVX512IFMASupport:=(_ebx and $200000)<>0;
+            _AVX512PFSupport:=(_ebx and $4000000)<>0;
+            _AVX512ERSupport:=(_ebx and $8000000)<>0;
+            _AVX512CDSupport:=(_ebx and $10000000)<>0;
+            _AVX512BWSupport:=(_ebx and $40000000)<>0;
+            _AVX512VLSupport:=(_ebx and $80000000)<>0;
+            _BMI1Support:=(_ebx and $8)<>0;
+            _BMI2Support:=(_ebx and $100)<>0;
+            _RTMSupport:=(_ebx and $800)<>0;
+          end;
       end;
       end;
 
 
 
 
@@ -215,6 +248,54 @@ unit cpu;
       end;
       end;
 
 
 
 
+    function AVX512FSupport: boolean;inline;
+      begin
+        result:=_AVX512FSupport;
+      end;
+
+
+    function AVX512DQSupport: boolean;inline;
+      begin
+        result:=_AVX512DQSupport;
+      end;
+
+
+    function AVX512IFMASupport: boolean;inline;    
+      begin
+        result:=_AVX512IFMASupport;
+      end;
+
+
+    function AVX512PFSupport: boolean;inline;    
+      begin
+        result:=_AVX512PFSupport;
+      end;
+
+
+    function AVX512ERSupport: boolean;inline;    
+      begin
+        result:=_AVX512ERSupport;
+      end;
+
+
+    function AVX512CDSupport: boolean;inline;    
+      begin
+        result:=_AVX512CDSupport;
+      end;
+
+
+    function AVX512BWSupport: boolean;inline;    
+      begin
+        result:=_AVX512BWSupport;
+      end;
+
+
+    function AVX512VLSupport: boolean;inline;    
+      begin
+        result:=_AVX512VLSupport;
+      end;
+
+
     function FMASupport: boolean;inline;
     function FMASupport: boolean;inline;
       begin
       begin
         result:=_FMASupport;
         result:=_FMASupport;