mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-08 04:48:07 +02:00
+ SPARC: implemented register spill replacement.
git-svn-id: trunk@26364 -
This commit is contained in:
parent
0afd95e840
commit
d2a9308181
@ -2134,7 +2134,7 @@ unit rgobj;
|
||||
if not spilled then
|
||||
exit;
|
||||
|
||||
{$if defined(x86) or defined(mips)}
|
||||
{$if defined(x86) or defined(mips) or defined(sparc)}
|
||||
{ Try replacing the register with the spilltemp. This is useful only
|
||||
for the i386,x86_64 that support memory locations for several instructions
|
||||
|
||||
@ -2149,7 +2149,7 @@ unit rgobj;
|
||||
mustbespilled:=false;
|
||||
end;
|
||||
end;
|
||||
{$endif defined(x86) or defined(mips)}
|
||||
{$endif defined(x86) or defined(mips) or defined(sparc)}
|
||||
|
||||
{
|
||||
There are registers that need are spilled. We generate the
|
||||
|
@ -37,6 +37,7 @@ unit rgcpu;
|
||||
function get_spill_subreg(r : tregister) : tsubregister;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;
|
||||
function do_spill_replace(list:TAsmList;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;override;
|
||||
end;
|
||||
|
||||
|
||||
@ -161,4 +162,53 @@ implementation
|
||||
inherited do_spill_written(list,pos,spilltemp,tempreg);
|
||||
end;
|
||||
|
||||
|
||||
function trgcpu.do_spill_replace(list:TAsmList;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;
|
||||
var
|
||||
opidx: longint;
|
||||
begin
|
||||
result:=false;
|
||||
{ Replace 'mov src,orgreg' with 'st src,spilltemp'
|
||||
and 'mov orgreg,dst' with 'ld spilltemp,dst' }
|
||||
if (abs(spilltemp.offset)>4095) then
|
||||
exit;
|
||||
if ((regtype=R_INTREGISTER) and (instr.opcode<>A_MOV)) or
|
||||
((regtype=R_FPUREGISTER) and (instr.opcode<>A_FMOVs) and (instr.opcode<>A_FMOVd)) then
|
||||
exit;
|
||||
{ Ignore mis-encoded stuff like 'mov %something,%y' }
|
||||
if (instr.ops<>2) or
|
||||
(instr.oper[0]^.typ<>top_reg) or
|
||||
(instr.oper[1]^.typ<>top_reg) or
|
||||
(getregtype(instr.oper[0]^.reg)<>regtype) or
|
||||
(getregtype(instr.oper[1]^.reg)<>regtype) then
|
||||
exit;
|
||||
opidx:=-1;
|
||||
if get_alias(getsupreg(instr.oper[0]^.reg))=orgreg then
|
||||
begin
|
||||
if (regtype=R_INTREGISTER) then
|
||||
instr.opcode:=A_LD
|
||||
else if (getsubreg(instr.oper[0]^.reg)=R_SUBFS) then
|
||||
instr.opcode:=A_LDF
|
||||
else
|
||||
instr.opcode:=A_LDDF;
|
||||
opidx:=0;
|
||||
end
|
||||
else if get_alias(getsupreg(instr.oper[1]^.reg))=orgreg then
|
||||
begin
|
||||
if (regtype=R_INTREGISTER) then
|
||||
instr.opcode:=A_ST
|
||||
else if (getsubreg(instr.oper[1]^.reg)=R_SUBFS) then
|
||||
instr.opcode:=A_STF
|
||||
else
|
||||
instr.opcode:=A_STDF;
|
||||
opidx:=1;
|
||||
end
|
||||
else
|
||||
InternalError(2013061002);
|
||||
instr.oper[opidx]^.typ:=top_ref;
|
||||
new(instr.oper[opidx]^.ref);
|
||||
instr.oper[opidx]^.ref^:=spilltemp;
|
||||
result:=true;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user