Support ABS intrinsic on ARM

This code will generate the following sequence on arm:
r1=dst
r0=src

movs r1, r0
rsbmi r1, r0, #0

movs will set the N-flag when the MSB of r0 is set, if it is set, rsb
will calculate dst:=0-src;

git-svn-id: trunk@21678 -
This commit is contained in:
masta 2012-06-21 20:12:36 +00:00
parent 3d9d484bfd
commit 59c726c829
2 changed files with 19 additions and 3 deletions

View File

@ -49,6 +49,7 @@ interface
procedure second_sin_real; override;
}
procedure second_prefetch; override;
procedure second_abs_long; override;
private
procedure load_fpu_location(out singleprec: boolean);
end;
@ -59,14 +60,14 @@ implementation
uses
globtype,systems,
cutils,verbose,globals,fmodule,
cpuinfo,
cpuinfo, defutil,
symconst,symdef,
aasmbase,aasmtai,aasmdata,aasmcpu,
cgbase,cgutils,
pass_1,pass_2,
cpubase,paramgr,
nbas,ncon,ncal,ncnv,nld,
tgobj,ncgutil,cgobj,cg64f32,rgobj,rgcpu,cgcpu;
tgobj,ncgutil,cgobj,cg64f32,rgobj,rgcpu,cgcpu, hlcgobj;
{*****************************************************************************
tarminlinenode
@ -338,6 +339,21 @@ implementation
end;
end;
procedure tarminlinenode.second_abs_long;
var
hregister : tregister;
opsize : tcgsize;
hp : taicpu;
begin
secondpass(left);
opsize:=def_cgsize(left.resultdef);
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
hregister:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
location:=left.location;
location.register:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_MOV,location.register,left.location.register), PF_S));
current_asmdata.CurrAsmList.concat(setcondition(taicpu.op_reg_reg_const(A_RSB,location.register,location.register, 0), C_MI));
end;
begin
cinlinenode:=tarminlinenode;

View File

@ -2746,7 +2746,7 @@ begin
def_system_macro('FPC_STATICRIPFIXED');
def_system_macro('FPC_VARIANTCOPY_FIXED');
def_system_macro('FPC_DYNARRAYCOPY_FIXED');
{$if defined(x86) or defined(powerpc) or defined(powerpc64)}
{$if defined(x86) or defined(powerpc) or defined(powerpc64) or defined(cpuarm)}
def_system_macro('FPC_HAS_INTERNAL_ABS_LONG');
{$endif}
def_system_macro('FPC_HAS_UNICODESTRING');