mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-08 10:48:12 +02:00
AVR: Add optimizations for sign testing, and a better Abs() implementation.
git-svn-id: trunk@42510 -
This commit is contained in:
parent
bf71795324
commit
91016c97a4
@ -1606,7 +1606,7 @@ unit cgcpu;
|
||||
procedure tcgavr.a_cmp_const_reg_label(list : TAsmList;size : tcgsize;
|
||||
cmp_op : topcmp;a : tcgint;reg : tregister;l : tasmlabel);
|
||||
var
|
||||
swapped : boolean;
|
||||
swapped , test_msb: boolean;
|
||||
tmpreg : tregister;
|
||||
i : byte;
|
||||
begin
|
||||
@ -1637,18 +1637,31 @@ unit cgcpu;
|
||||
end;
|
||||
end;
|
||||
|
||||
if swapped then
|
||||
list.concat(taicpu.op_reg_reg(A_CP,NR_R1,reg))
|
||||
else
|
||||
list.concat(taicpu.op_reg_reg(A_CP,reg,NR_R1));
|
||||
|
||||
for i:=2 to tcgsize2size[size] do
|
||||
{ If doing a signed test for x<0, we can simply test the sign bit
|
||||
of the most significant byte }
|
||||
if (cmp_op in [OC_LT,OC_GTE]) and
|
||||
(not swapped) then
|
||||
begin
|
||||
for i:=2 to tcgsize2size[size] do
|
||||
reg:=GetNextReg(reg);
|
||||
|
||||
list.concat(taicpu.op_reg_reg(A_CP,reg,NR_R1));
|
||||
end
|
||||
else
|
||||
begin
|
||||
reg:=GetNextReg(reg);
|
||||
if swapped then
|
||||
list.concat(taicpu.op_reg_reg(A_CPC,NR_R1,reg))
|
||||
list.concat(taicpu.op_reg_reg(A_CP,NR_R1,reg))
|
||||
else
|
||||
list.concat(taicpu.op_reg_reg(A_CPC,reg,NR_R1));
|
||||
list.concat(taicpu.op_reg_reg(A_CP,reg,NR_R1));
|
||||
|
||||
for i:=2 to tcgsize2size[size] do
|
||||
begin
|
||||
reg:=GetNextReg(reg);
|
||||
if swapped then
|
||||
list.concat(taicpu.op_reg_reg(A_CPC,NR_R1,reg))
|
||||
else
|
||||
list.concat(taicpu.op_reg_reg(A_CPC,reg,NR_R1));
|
||||
end;
|
||||
end;
|
||||
|
||||
a_jmp_cond(list,cmp_op,l);
|
||||
|
@ -202,6 +202,29 @@ interface
|
||||
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
|
||||
end;
|
||||
|
||||
if (not unsigned) and
|
||||
(right.location.loc=LOC_CONSTANT) and
|
||||
(right.location.value=0) and
|
||||
(getresflags(unsigned) in [F_LT,F_GE]) then
|
||||
begin
|
||||
{ This is a simple sign test, where we can just test the msb }
|
||||
tmpreg1:=left.location.register;
|
||||
for i:=2 to tcgsize2size[left.location.size] do
|
||||
begin
|
||||
if i=5 then
|
||||
tmpreg1:=left.location.registerhi
|
||||
else
|
||||
tmpreg1:=cg.GetNextReg(tmpreg1);
|
||||
end;
|
||||
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,tmpreg1,NR_R1));
|
||||
|
||||
location_reset(location,LOC_FLAGS,OS_NO);
|
||||
location.resflags:=getresflags(unsigned);
|
||||
|
||||
exit;
|
||||
end;
|
||||
|
||||
if right.location.loc=LOC_CONSTANT then
|
||||
begin
|
||||
{ decrease register pressure on registers >= r16 }
|
||||
|
@ -26,10 +26,12 @@ unit navrinl;
|
||||
interface
|
||||
|
||||
uses
|
||||
node,ninl,ncginl;
|
||||
node,ninl,ncginl, aasmbase;
|
||||
|
||||
type
|
||||
tavrinlinenode = class(tcginlinenode)
|
||||
procedure second_abs_long; override;
|
||||
|
||||
function pass_typecheck_cpu:tnode;override;
|
||||
function first_cpu : tnode;override;
|
||||
procedure pass_generate_code_cpu;override;
|
||||
@ -42,11 +44,33 @@ unit navrinl;
|
||||
aasmdata,
|
||||
aasmcpu,
|
||||
symdef,
|
||||
defutil,
|
||||
hlcgobj,
|
||||
pass_2,
|
||||
cgbase, cgobj, cgutils,
|
||||
cpubase;
|
||||
|
||||
procedure tavrinlinenode.second_abs_long;
|
||||
var
|
||||
hl: TAsmLabel;
|
||||
size: TCgSize;
|
||||
begin
|
||||
secondpass(left);
|
||||
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
|
||||
|
||||
location:=left.location;
|
||||
location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,left.resultdef);
|
||||
|
||||
size:=def_cgsize(left.resultdef);
|
||||
|
||||
current_asmdata.getjumplabel(hl);
|
||||
cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,size,OC_GTE,0,left.location.register,hl);
|
||||
cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,size,left.location.register,location.register);
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList,hl);
|
||||
end;
|
||||
|
||||
|
||||
function tavrinlinenode.pass_typecheck_cpu : tnode;
|
||||
begin
|
||||
Result:=nil;
|
||||
|
Loading…
Reference in New Issue
Block a user