mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 05:59:28 +02:00
+ AArch64 internal bsf/bsr support
git-svn-id: trunk@29979 -
This commit is contained in:
parent
b40a4d1b5a
commit
a8d05b66e2
@ -80,6 +80,8 @@ interface
|
||||
procedure a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize: tcgsize; mmreg, intreg: tregister; shuffle: pmmshuffle); override;
|
||||
|
||||
procedure a_opmm_reg_reg(list: TAsmList; Op: TOpCG; size: tcgsize; src, dst: tregister; shuffle: pmmshuffle); override;
|
||||
|
||||
procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: tcgsize; src, dst: TRegister); override;
|
||||
{ comparison operations }
|
||||
procedure a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);override;
|
||||
procedure a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);override;
|
||||
@ -1076,6 +1078,43 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgaarch64.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: tcgsize; src, dst: TRegister);
|
||||
var
|
||||
bitsize,
|
||||
signbit: longint;
|
||||
begin
|
||||
if size in [OS_64,OS_S64] then
|
||||
begin
|
||||
bitsize:=64;
|
||||
signbit:=6;
|
||||
end
|
||||
else
|
||||
begin
|
||||
bitsize:=32;
|
||||
signbit:=5;
|
||||
end;
|
||||
{ source is 0 -> dst will have to become 255 }
|
||||
list.concat(taicpu.op_reg_const(A_CMP,src,0));
|
||||
if reverse then
|
||||
begin
|
||||
list.Concat(taicpu.op_reg_reg(A_CLZ,dst,src));
|
||||
{ xor 31/63 is the same as setting the lower 5/6 bits to
|
||||
"31/63-(lower 5/6 bits of dst)" }
|
||||
list.Concat(taicpu.op_reg_reg_const(A_EOR,dst,dst,bitsize-1));
|
||||
end
|
||||
else
|
||||
begin
|
||||
list.Concat(taicpu.op_reg_reg(A_RBIT,dst,src));
|
||||
list.Concat(taicpu.op_reg_reg(A_CLZ,dst,dst));
|
||||
end;
|
||||
{ set dst to -1 if src was 0 }
|
||||
list.Concat(taicpu.op_reg_reg_reg_cond(A_CSINV,dst,dst,src,C_NE));
|
||||
{ mask the -1 to 255 if src was 0 (anyone find a two-instruction
|
||||
branch-free version? All of mine are 3...) }
|
||||
list.Concat(setoppostfix(taicpu.op_reg_reg(A_UXT,dst,dst),PF_B));
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgaarch64.a_load_reg_ref_unaligned(list: TAsmList; fromsize, tosize: tcgsize; register: tregister; const ref: treference);
|
||||
var
|
||||
href: treference;
|
||||
|
@ -3839,7 +3839,7 @@ if (target_info.abi = abi_eabihf) then
|
||||
{$endif ARM}
|
||||
|
||||
{ inline bsf/bsr implementation }
|
||||
{$if defined(i386) or defined(x86_64)}
|
||||
{$if defined(i386) or defined(x86_64) or defined(aarch64)}
|
||||
def_system_macro('FPC_HAS_INTERNAL_BSF');
|
||||
def_system_macro('FPC_HAS_INTERNAL_BSR');
|
||||
{$endif}
|
||||
|
@ -987,23 +987,23 @@ function fpc_SarInt64(Const AValue : Int64;const Shift : Byte): Int64;compilerpr
|
||||
{$endif FPC_HAS_INTERNAL_SAR_QWORD}
|
||||
|
||||
{$ifdef FPC_HAS_INTERNAL_BSF}
|
||||
{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm)}
|
||||
{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm) or defined(cpuaarch64)}
|
||||
{$define FPC_HAS_INTERNAL_BSF_BYTE}
|
||||
{$define FPC_HAS_INTERNAL_BSF_WORD}
|
||||
{$define FPC_HAS_INTERNAL_BSF_DWORD}
|
||||
{$endif}
|
||||
{$if defined(cpux86_64)}
|
||||
{$if defined(cpux86_64) or defined(cpuaarch64)}
|
||||
{$define FPC_HAS_INTERNAL_BSF_QWORD}
|
||||
{$endif}
|
||||
{$endif}
|
||||
|
||||
{$ifdef FPC_HAS_INTERNAL_BSR}
|
||||
{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm)}
|
||||
{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm) or defined(cpuaarch64)}
|
||||
{$define FPC_HAS_INTERNAL_BSR_BYTE}
|
||||
{$define FPC_HAS_INTERNAL_BSR_WORD}
|
||||
{$define FPC_HAS_INTERNAL_BSR_DWORD}
|
||||
{$endif}
|
||||
{$if defined(cpux86_64)}
|
||||
{$if defined(cpux86_64) or defined(cpuaarch64)}
|
||||
{$define FPC_HAS_INTERNAL_BSR_QWORD}
|
||||
{$endif}
|
||||
{$endif}
|
||||
|
Loading…
Reference in New Issue
Block a user