mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 07:39:13 +02:00
+ replace registers to spill in mov instructions and convert them into ldr/str
git-svn-id: trunk@26677 -
This commit is contained in:
parent
a1dfaa54dd
commit
829764e96b
@ -43,6 +43,8 @@ unit rgcpu;
|
|||||||
public
|
public
|
||||||
procedure do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);override;
|
procedure do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);override;
|
||||||
procedure do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);override;
|
procedure do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);override;
|
||||||
|
function do_spill_replace(list : TAsmList;instr : taicpu;
|
||||||
|
orgreg : tsuperregister;const spilltemp : treference) : boolean;override;
|
||||||
procedure add_constraints(reg:tregister);override;
|
procedure add_constraints(reg:tregister);override;
|
||||||
function get_spill_subreg(r:tregister) : tsubregister;override;
|
function get_spill_subreg(r:tregister) : tsubregister;override;
|
||||||
end;
|
end;
|
||||||
@ -280,6 +282,48 @@ unit rgcpu;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function trgcpu.do_spill_replace(list:TAsmList;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;
|
||||||
|
var
|
||||||
|
b : byte;
|
||||||
|
begin
|
||||||
|
result:=false;
|
||||||
|
if abs(spilltemp.offset)>4095 then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
{ Replace 'mov dst,orgreg' with 'ldr dst,spilltemp'
|
||||||
|
and 'mov orgreg,src' with 'str dst,spilltemp' }
|
||||||
|
with instr do
|
||||||
|
begin
|
||||||
|
if (opcode=A_MOV) and (ops=2) and (oper[1]^.typ=top_reg) and (oper[0]^.typ=top_reg) then
|
||||||
|
begin
|
||||||
|
if (getregtype(oper[0]^.reg)=regtype) and
|
||||||
|
(get_alias(getsupreg(oper[0]^.reg))=orgreg) and
|
||||||
|
(get_alias(getsupreg(oper[1]^.reg))<>orgreg) then
|
||||||
|
begin
|
||||||
|
{ str expects the register in oper[0] }
|
||||||
|
oper[0]^.typ:=top_reg;
|
||||||
|
oper[0]^.reg:=oper[1]^.reg;
|
||||||
|
oper[1]^.typ:=top_ref;
|
||||||
|
new(oper[1]^.ref);
|
||||||
|
oper[1]^.ref^:=spilltemp;
|
||||||
|
opcode:=A_STR;
|
||||||
|
result:=true;
|
||||||
|
end
|
||||||
|
else if (getregtype(oper[1]^.reg)=regtype) and
|
||||||
|
(get_alias(getsupreg(oper[1]^.reg))=orgreg) and
|
||||||
|
(get_alias(getsupreg(oper[0]^.reg))<>orgreg) then
|
||||||
|
begin
|
||||||
|
oper[1]^.typ:=top_ref;
|
||||||
|
new(oper[1]^.ref);
|
||||||
|
oper[1]^.ref^:=spilltemp;
|
||||||
|
opcode:=A_LDR;
|
||||||
|
result:=true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure trgcpu.add_constraints(reg:tregister);
|
procedure trgcpu.add_constraints(reg:tregister);
|
||||||
var
|
var
|
||||||
supreg,i : Tsuperregister;
|
supreg,i : Tsuperregister;
|
||||||
|
@ -2137,7 +2137,7 @@ unit rgobj;
|
|||||||
if not spilled then
|
if not spilled then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
{$if defined(x86) or defined(mips) or defined(sparc)}
|
{$if defined(x86) or defined(mips) or defined(sparc) or defined(arm)}
|
||||||
{ Try replacing the register with the spilltemp. This is useful only
|
{ Try replacing the register with the spilltemp. This is useful only
|
||||||
for the i386,x86_64 that support memory locations for several instructions
|
for the i386,x86_64 that support memory locations for several instructions
|
||||||
|
|
||||||
@ -2152,7 +2152,7 @@ unit rgobj;
|
|||||||
mustbespilled:=false;
|
mustbespilled:=false;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
{$endif defined(x86) or defined(mips) or defined(sparc)}
|
{$endif defined(x86) or defined(mips) or defined(sparc) or defined(arm)}
|
||||||
|
|
||||||
{
|
{
|
||||||
There are registers that need are spilled. We generate the
|
There are registers that need are spilled. We generate the
|
||||||
|
Loading…
Reference in New Issue
Block a user