+ handle abs(real) internally for LLVM, as the generic code calls a helper

that is not implemented for some architectures

git-svn-id: trunk@31656 -
This commit is contained in:
Jonas Maebe 2015-09-12 23:33:53 +00:00
parent 8ff5371a6c
commit 616dbead35

View File

@ -33,6 +33,7 @@ interface
tllvminlinenode = class(tcginlinenode)
protected
function first_get_frame: tnode; override;
function first_abs_real: tnode; override;
public
procedure second_length; override;
end;
@ -44,7 +45,7 @@ implementation
verbose,globtype,constexp,
aasmbase, aasmdata,
symtype,symdef,defutil,
ncal,ncon,ninl,
nutils,nadd,nbas,ncal,ncon,nflw,ninl,nld,nmat,
pass_2,
cgbase,cgutils,tgobj,hlcgobj,
cpubase;
@ -56,6 +57,62 @@ implementation
ccallparanode.create(genintconstnode(0),nil));
end;
{ in general, generate regular expression rather than intrinsics: according
to the "Performance Tips for Frontend Authors", "The optimizer is quite
good at reasoning about general control flow and arithmetic, it is not
anywhere near as strong at reasoning about the various intrinsics. If
profitable for code generation purposes, the optimizer will likely form
the intrinsics itself late in the optimization pipeline." }
function tllvminlinenode.first_abs_real: tnode;
var
lefttemp,
resulttemp: ttempcreatenode;
stat: tstatementnode;
begin
result:=internalstatements(stat);
lefttemp:=ctempcreatenode.create(left.resultdef,left.resultdef.size,tt_persistent,true);
{ assigned twice -> will be spilled if put in register }
resulttemp:=ctempcreatenode.create(resultdef,resultdef.size,tt_persistent,false);
addstatement(stat,lefttemp);
addstatement(stat,resulttemp);
{ lefttemp:=left }
addstatement(stat,
cassignmentnode.create(ctemprefnode.create(lefttemp),left)
);
{ if lefttemp>=0 then
resulttemp:=lefttemp
else
resulttemp:=-lefttemp
}
addstatement(stat,
cifnode.create(
caddnode.create(
gten,
ctemprefnode.create(lefttemp),
crealconstnode.create(0.0,left.resultdef)
),
cassignmentnode.create(
ctemprefnode.create(resulttemp),
ctemprefnode.create(lefttemp)
),
cassignmentnode.create(
ctemprefnode.create(resulttemp),
cunaryminusnode.create(ctemprefnode.create(lefttemp))
)
)
);
addstatement(stat,ctempdeletenode.create(lefttemp));
addstatement(stat,ctempdeletenode.create_normal_temp(resulttemp));
{ return resulttemp }
addstatement(stat,ctemprefnode.create(resulttemp));
{ reused }
left:=nil;
end;
procedure tllvminlinenode.second_length;
var