浏览代码

* bsr implementation for armv5+ using clz

git-svn-id: trunk@22310 -
florian 13 年之前
父节点
当前提交
d63ebe6464
共有 3 个文件被更改,包括 23 次插入8 次删除
  1. 8 1
      compiler/arm/cgcpu.pas
  2. 14 6
      compiler/options.pas
  3. 1 1
      rtl/inc/systemh.inc

+ 8 - 1
compiler/arm/cgcpu.pas

@@ -1517,9 +1517,16 @@ unit cgcpu;
 
     procedure tcgarm.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister);
       begin
-        Comment(V_Error,'tcgarm.a_bit_scan_reg_reg method not implemented');
+        if reverse then
+          begin
+            list.Concat(taicpu.op_reg_reg(A_CLZ,dst,src));
+            list.Concat(taicpu.op_reg_reg_const(A_RSB,dst,dst,31));
+          end
+        else
+          internalerror(201209041);
       end;
 
+
     procedure tcgarm.a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel);
       begin
         a_reg_alloc(list,NR_DEFAULTFLAGS);

+ 14 - 6
compiler/options.pas

@@ -2776,12 +2776,6 @@ begin
   def_system_macro('FPC_HAS_INTERNAL_SAR');
 { $endif}
 
-{ inline bsf/bsr implementation }
-{$if defined(x86) or defined(x86_64)}
-  def_system_macro('FPC_HAS_INTERNAL_BSF');
-  def_system_macro('FPC_HAS_INTERNAL_BSR');
-{$endif}
-
 {$ifdef powerpc64}
   def_system_macro('FPC_HAS_LWSYNC');
 {$endif}
@@ -3265,6 +3259,20 @@ if (target_info.abi = abi_eabihf) then
     def_system_macro('FPC_DOUBLE_HILO_SWAPPED');
 {$endif ARM}
 
+{ inline bsf/bsr implementation }
+{$if defined(x86) or defined(x86_64)}
+  def_system_macro('FPC_HAS_INTERNAL_BSF');
+  def_system_macro('FPC_HAS_INTERNAL_BSR');
+{$endif}
+{$if defined(arm)}
+  { it is determined during system unit compilation if clz is used for bsf or not,
+    this is not perfect but the current implementation bsf/bsr does not allow another
+    solution }
+  if CPUARM_HAS_CLZ in cpu_capabilities[init_settings.cputype] then
+    def_system_macro('FPC_HAS_INTERNAL_BSR');
+{$endif}
+
+
   { Section smartlinking conflicts with import sections on Windows }
   if GenerateImportSection and
      (target_info.system in [system_i386_win32,system_x86_64_win64]) then

+ 1 - 1
rtl/inc/systemh.inc

@@ -829,7 +829,7 @@ function SarInt64(Const AValue : Int64;const Shift : Byte = 1): Int64; [external
 {$endif}
 
 {$ifdef FPC_HAS_INTERNAL_BSR}
-{$if defined(cpui386) or defined(cpux86_64)}
+{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm)}
 {$define FPC_HAS_INTERNAL_BSR_BYTE}
 {$define FPC_HAS_INTERNAL_BSR_WORD}
 {$define FPC_HAS_INTERNAL_BSR_DWORD}