소스 검색

+ xtensa: make use of nsau to implement Bsr*

git-svn-id: trunk@46963 -
florian 4 년 전
부모
커밋
7f53d04ffd
4개의 변경된 파일37개의 추가작업 그리고 2개의 파일을 삭제
  1. 10 0
      compiler/options.pas
  2. 24 0
      compiler/xtensa/cgcpu.pas
  3. 2 1
      compiler/xtensa/cpuinfo.pas
  4. 1 1
      rtl/inc/systemh.inc

+ 10 - 0
compiler/options.pas

@@ -4619,6 +4619,16 @@ begin
     end;
 {$endif}
 
+{$if defined(xtensa)}
+  { it is determined during system unit compilation if nsau is used for bsr or not,
+    this is not perfect but the current implementation bsf/bsr does not allow another
+    solution }
+  if CPUXTENSA_HAS_NSAx in cpu_capabilities[init_settings.cputype] then
+    begin
+      def_system_macro('FPC_HAS_INTERNAL_BSR');
+    end;
+{$endif}
+
 {$if defined(powerpc64)}
   { on sysv targets, default to elfv2 for little endian and to elfv1 for
     big endian (unless specified otherwise). As the gcc man page says:

+ 24 - 0
compiler/xtensa/cgcpu.pas

@@ -69,6 +69,8 @@ interface
         procedure a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);override;
         procedure a_jmp_always(list: TAsmList; l: TAsmLabel);override;
 
+        procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: TCGSize; src, dst: TRegister);override;
+
         procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: tresflags; reg: TRegister);override;
 
         procedure g_concatcopy(list : TAsmList; const source,dest : treference; len : tcgint);override;
@@ -1270,6 +1272,28 @@ implementation
       end;
 
 
+    procedure tcgcpu.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: TCGSize; src, dst: TRegister);
+      var
+        ai: taicpu;
+        tmpreg: TRegister;
+      begin
+        if reverse then
+          begin
+            list.Concat(taicpu.op_reg_reg(A_NSAU,dst,src));
+            tmpreg:=getintregister(list,OS_INT);
+            a_load_const_reg(list,OS_INT,31,tmpreg);
+            a_op_reg_reg_reg(list,OP_SUB,OS_INT,dst,tmpreg,dst);
+            tmpreg:=getintregister(list,OS_INT);
+            a_load_const_reg(list,OS_INT,255,tmpreg);
+            ai:=taicpu.op_reg_reg_reg(A_MOV,dst,tmpreg,src);
+            ai.condition:=C_EQZ;
+            list.Concat(ai);
+          end
+        else
+          Internalerror(2020092604);
+      end;
+
+
     procedure tcg64fxtensa.a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);
       var
         instr: taicpu;

+ 2 - 1
compiler/xtensa/cpuinfo.pas

@@ -137,6 +137,7 @@ Const
       (
         CPUXTENSA_REGWINDOW,
         CPUXTENSA_HAS_SEXT,
+        CPUXTENSA_HAS_NSAx,
         CPUXTENSA_HAS_BOOLEAN_OPTION,
         CPUXTENSA_HAS_MUL32HIGH,
         CPUXTENSA_HAS_DIV,
@@ -154,7 +155,7 @@ Const
      (
        { cpu_none     } [],
        { cpu_lx106    } [],
-       { cpu_lx6      } [CPUXTENSA_REGWINDOW, CPUXTENSA_HAS_SEXT, CPUXTENSA_HAS_BOOLEAN_OPTION, CPUXTENSA_HAS_MUL32HIGH, CPUXTENSA_HAS_DIV, CPUXTENSA_HAS_LOOPS]
+       { cpu_lx6      } [CPUXTENSA_REGWINDOW, CPUXTENSA_HAS_SEXT, CPUXTENSA_HAS_NSAx, CPUXTENSA_HAS_BOOLEAN_OPTION, CPUXTENSA_HAS_MUL32HIGH, CPUXTENSA_HAS_DIV, CPUXTENSA_HAS_LOOPS]
      );
 
    fpu_capabilities : array[tfputype] of set of tfpuflags =

+ 1 - 1
rtl/inc/systemh.inc

@@ -1143,7 +1143,7 @@ function fpc_SarInt64(Const AValue : Int64;const Shift : Byte): Int64;compilerpr
 {$endif}
 
 {$ifdef FPC_HAS_INTERNAL_BSR}
-{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm) or defined(cpuaarch64) or defined(cpupowerpc32) or defined(cpupowerpc64)}
+{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm) or defined(cpuaarch64) or defined(cpupowerpc32) or defined(cpupowerpc64) or defined(cpuxtensa)}
 {$define FPC_HAS_INTERNAL_BSR_BYTE}
 {$define FPC_HAS_INTERNAL_BSR_WORD}
 {$define FPC_HAS_INTERNAL_BSR_DWORD}