Prechádzať zdrojové kódy

+ generic popcnt support

git-svn-id: trunk@22290 -
florian 13 rokov pred
rodič
commit
ff12d63248

+ 21 - 2
compiler/ninl.pas

@@ -78,6 +78,7 @@ interface
           function first_unbox: tnode; virtual; abstract;
           function first_assigned: tnode; virtual;
           function first_assert: tnode; virtual;
+          function first_popcnt: tnode; virtual;
 
         private
           function handle_str: tnode;
@@ -3475,9 +3476,10 @@ implementation
          in_sar_x,
          in_sar_x_y,
          in_bsf_x,
-         in_bsr_x,
-         in_popcnt_x:
+         in_bsr_x:
            expectloc:=LOC_REGISTER;
+         in_popcnt_x:
+           result:=first_popcnt;
          in_new_x:
            result:=first_new;
          in_box_x:
@@ -3827,6 +3829,23 @@ implementation
        end;
 
 
+     function tinlinenode.first_popcnt: tnode;
+       var
+         suffix : string;
+       begin
+         case torddef(left.resultdef).ordtype of
+           u8bit: suffix:='byte';
+           u16bit: suffix:='word';
+           u32bit: suffix:='dword';
+           u64bit: suffix:='qword';
+         else
+           internalerror(2012082601);
+         end;
+         result:=ccallnode.createintern('fpc_popcnt_'+suffix,ccallparanode.create(left,nil));
+         left:=nil;
+       end;
+
+
      function tinlinenode.handle_box: tnode;
        begin
          result:=nil;

+ 0 - 5
compiler/options.pas

@@ -2781,11 +2781,6 @@ begin
   def_system_macro('FPC_HAS_INTERNAL_BSX');
 {$endif}
 
-{ inline bsf/bsr implementation }
-{$if defined(x86) or defined(x86_64)}
-  def_system_macro('FPC_HAS_INTERNAL_POPCNT');
-{$endif}
-
 {$ifdef powerpc64}
   def_system_macro('FPC_HAS_LWSYNC');
 {$endif}

+ 6 - 0
compiler/x86/nx86inl.pas

@@ -44,6 +44,7 @@ interface
           function first_sin_real: tnode; override;
           function first_round_real: tnode; override;
           function first_trunc_real: tnode; override;
+          function first_popcnt: tnode; override;
           { second pass override to generate these nodes }
           procedure second_IncludeExclude;override;
           procedure second_pi; override;
@@ -171,6 +172,11 @@ implementation
            end;
        end;
 
+     function tx86inlinenode.first_popcnt: tnode;
+       begin
+        Result:=inherited first_popcnt;
+       end;
+
 
      procedure tx86inlinenode.second_Pi;
        begin

+ 7 - 0
rtl/inc/compproc.inc

@@ -502,6 +502,13 @@ function fpc_shl_int64(value,shift : int64) : int64; compilerproc;
 function fpc_shr_int64(value,shift : int64) : int64; compilerproc;
 {$endif  FPC_INCLUDE_SOFTWARE_SHIFT_INT64}
 
+
+function fpc_popcnt_byte(AValue : Byte): Byte;compilerproc;
+function fpc_popcnt_word(AValue : Word): Word;compilerproc;
+function fpc_popcnt_dword(AValue : DWord): DWord;compilerproc;
+function fpc_popcnt_qword(Const AValue : QWord): QWord;compilerproc;
+
+
 {$ifndef FPUNONE}
 function fpc_abs_real(d : ValReal) : ValReal;compilerproc;
 function fpc_arctan_real(d : ValReal) : ValReal;compilerproc;{$ifdef MATHINLINE}inline;{$endif}

+ 38 - 3
rtl/inc/generic.inc

@@ -2445,12 +2445,47 @@ function BsrQWord(Const AValue : QWord): cardinal;
 {$endif}
 {$endif}
 
-{$ifndef FPC_HAS_INTERNAL_POPCNT_QWORD}
+const
+  PopCntData : array[0..15] of byte = (0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4);
+
+function fpc_PopCnt_byte(AValue : Byte): Byte;[Public,Alias:'FPC_POPCNT_BYTE'];compilerproc;
+  var
+    i : SizeInt;
+  begin
+    Result:=PopCntData[AValue and $f]+PopCntData[(AValue shr 4) and $f];
+  end;
+
+
+function fpc_PopCnt_word(AValue : Word): Word;[Public,Alias:'FPC_POPCNT_WORD'];compilerproc;
+  var
+    i : SizeInt;
+  begin
+    Result:=0;
+    for i:=0 to 3 do
+      begin
+        inc(Result,PopCntData[AValue and $f]);
+        AValue:=AValue shr 4;
+      end;
+  end;
+
+
+function fpc_PopCnt_dword(AValue : DWord): DWord;[Public,Alias:'FPC_POPCNT_DWORD'];compilerproc;
+  var
+    i : SizeInt;
+  begin
+    Result:=0;
+    for i:=0 to 7 do
+      begin
+        inc(Result,PopCntData[AValue and $f]);
+        AValue:=AValue shr 4;
+      end;
+  end;
+
+
 {$ifndef FPC_SYSTEM_HAS_POPCNT_QWORD}
-function PopCnt(Const AValue : QWord): QWord;
+function fpc_PopCnt_qword(Const AValue : QWord): QWord;[Public,Alias:'FPC_POPCNT_QWORD'];compilerproc;
   begin
     Result:=PopCnt(lo(AValue))+PopCnt(hi(AValue))
   end;
 {$endif}
-{$endif}
 

+ 0 - 31
rtl/inc/systemh.inc

@@ -860,41 +860,10 @@ function BsfQWord(Const AValue : QWord): cardinal;{$ifdef SYSTEMINLINE}inline;{$
 function BsrQWord(Const AValue : QWord): cardinal;{$ifdef SYSTEMINLINE}inline;{$endif}
 {$endif FPC_HAS_INTERNAL_BSF_QWORD}
 
-{$ifdef FPC_HAS_INTERNAL_POPCNT}
-{$if defined(cpui386) or defined(cpux86_64)}
-{$define FPC_HAS_INTERNAL_POPCNT_BYTE}
-{$define FPC_HAS_INTERNAL_POPCNT_WORD}
-{$define FPC_HAS_INTERNAL_POPCNT_DWORD}
-{$endif}
-{$if defined(cpux86_64)}
-{$define FPC_HAS_INTERNAL_POPCNT_QWORD}
-{$endif}
-{$endif}
-
-
-{$ifdef FPC_HAS_INTERNAL_POPCNT_BYTE}
 function PopCnt(Const AValue: Byte): Byte;[internproc:fpc_in_popcnt_x];
-{$else}
-function PopCnt(Const AValue: Byte): Byte;{$ifdef SYSTEMINLINE}inline;{$endif}
-{$endif FPC_HAS_INTERNAL_POPCNT_BYTE}
-
-{$ifdef FPC_HAS_INTERNAL_POPCNT_WORD}
 function PopCnt(Const AValue: Word): Word;[internproc:fpc_in_popcnt_x];
-{$else}
-function PopCnt(Const AValue: Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
-{$endif FPC_HAS_INTERNAL_POPCNT_WORD}
-
-{$ifdef FPC_HAS_INTERNAL_POPCNT_DWORD}
 function PopCnt(Const AValue : DWord): DWord;[internproc:fpc_in_popcnt_x];
-{$else}
-function PopCnt(Const AValue : DWord): DWord;
-{$endif FPC_HAS_INTERNAL_POPCNT_DWORD}
-
-{$ifdef FPC_HAS_INTERNAL_POPCNT_QWORD}
 function PopCnt(Const AValue : QWord): QWord;[internproc:fpc_in_popcnt_x];
-{$else}
-function PopCnt(Const AValue : QWord): QWord;
-{$endif FPC_HAS_INTERNAL_POPCNT_QWORD}
 
 {$ifndef FPUNONE}
 { float math routines }