Signed modulus by 2 on ARM with no division is optimized to a series of instructions instead of calling fpc_mod_longint.

An ASR is removed from signed division by 2.

git-svn-id: trunk@24778 -
This commit is contained in:
Jeppe Johansen 2013-06-02 14:44:06 +00:00
parent 7f2750f188
commit 570b40faed

View File

@ -58,7 +58,7 @@ implementation
symtype,symconst,symtable,
cgbase,cgobj,hlcgobj,cgutils,
pass_2,procinfo,
ncon,ncnv,ncal,
ncon,ncnv,ncal,ninl,
cpubase,cpuinfo,
ncgutil,
nadd,pass_1,symdef;
@ -99,6 +99,17 @@ implementation
end;
left:=nil;
end
else if (nodetype=modn) and
(is_signed(left.resultdef)) and
(right.nodetype=ordconstn) and
(tordconstnode(right).value=2) then
begin
// result:=(0-(left and 1)) and (1+(sarlongint(left,31) shl 1))
result:=caddnode.create(andn,caddnode.create(subn,cordconstnode.create(0,sinttype,false),caddnode.create(andn,left,cordconstnode.create(1,sinttype,false))),
caddnode.create(addn,cordconstnode.create(1,sinttype,false),
cshlshrnode.create(shln,cinlinenode.create(in_sar_x_y,false,ccallparanode.create(cordconstnode.create(31,sinttype,false),ccallparanode.Create(left.getcopy,nil))),cordconstnode.create(1,sinttype,false))));
left:=nil;
end
else
result:=inherited first_moddivint;
end;
@ -135,7 +146,10 @@ implementation
begin
helper1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
helper2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,31,numerator,helper1);
if power = 1 then
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,numerator,helper1)
else
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,31,numerator,helper1);
if current_settings.cputype in cpu_thumb then
begin
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,32-power,helper1);