+ AArch64 internal bsf/bsr support

git-svn-id: trunk@29979 -
This commit is contained in:
Jonas Maebe 2015-02-23 22:57:02 +00:00
parent b40a4d1b5a
commit a8d05b66e2
3 changed files with 44 additions and 5 deletions

View File

@ -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;

View File

@ -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}

View File

@ -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}