+ SPARC: implemented register spill replacement.

git-svn-id: trunk@26364 -
This commit is contained in:
sergei 2014-01-03 08:14:43 +00:00
parent 0afd95e840
commit d2a9308181
2 changed files with 52 additions and 2 deletions

View File

@ -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

View File

@ -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.