mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-22 08:09:29 +02:00
* more spilling rewrites
This commit is contained in:
parent
feeba0ede6
commit
f5471aef6e
@ -487,8 +487,12 @@ interface
|
||||
tai_regalloc = class(tai)
|
||||
reg : tregister;
|
||||
ratype : TRegAllocType;
|
||||
constructor alloc(r : tregister);
|
||||
constructor dealloc(r : tregister);
|
||||
{ reg(de)alloc belongs to this instruction, this
|
||||
is only used for automatic inserted (de)alloc for
|
||||
imaginary register and required for spilling code }
|
||||
instr : tai;
|
||||
constructor alloc(r : tregister;ainstr:tai);
|
||||
constructor dealloc(r : tregister;ainstr:tai);
|
||||
constructor sync(r : tregister);
|
||||
constructor resize(r : tregister);
|
||||
constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
|
||||
@ -1717,21 +1721,23 @@ implementation
|
||||
tai_regalloc
|
||||
*****************************************************************************}
|
||||
|
||||
constructor tai_regalloc.alloc(r : tregister);
|
||||
constructor tai_regalloc.alloc(r : tregister;ainstr:tai);
|
||||
begin
|
||||
inherited create;
|
||||
typ:=ait_regalloc;
|
||||
ratype:=ra_alloc;
|
||||
reg:=r;
|
||||
instr:=ainstr;
|
||||
end;
|
||||
|
||||
|
||||
constructor tai_regalloc.dealloc(r : tregister);
|
||||
constructor tai_regalloc.dealloc(r : tregister;ainstr:tai);
|
||||
begin
|
||||
inherited create;
|
||||
typ:=ait_regalloc;
|
||||
ratype:=ra_dealloc;
|
||||
reg:=r;
|
||||
instr:=ainstr;
|
||||
end;
|
||||
|
||||
|
||||
@ -2224,7 +2230,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.89 2004-09-26 17:45:29 peter
|
||||
Revision 1.90 2004-10-05 20:41:01 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.89 2004/09/26 17:45:29 peter
|
||||
* simple regvar support, not yet finished
|
||||
|
||||
Revision 1.88 2004/08/15 13:30:18 florian
|
||||
|
@ -708,13 +708,13 @@ implementation
|
||||
|
||||
procedure tcg.a_reg_alloc(list : taasmoutput;r : tregister);
|
||||
begin
|
||||
list.concat(tai_regalloc.alloc(r));
|
||||
list.concat(tai_regalloc.alloc(r,nil));
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg.a_reg_dealloc(list : taasmoutput;r : tregister);
|
||||
begin
|
||||
list.concat(tai_regalloc.dealloc(r));
|
||||
list.concat(tai_regalloc.dealloc(r,nil));
|
||||
end;
|
||||
|
||||
|
||||
@ -2226,7 +2226,10 @@ finalization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.173 2004-09-29 18:55:40 florian
|
||||
Revision 1.174 2004-10-05 20:41:01 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.173 2004/09/29 18:55:40 florian
|
||||
* fixed more sparc overflow stuff
|
||||
* fixed some op64 stuff for sparc
|
||||
|
||||
|
@ -229,7 +229,7 @@ unit cgcpu;
|
||||
begin
|
||||
{ Release PIC register }
|
||||
if cs_create_pic in aktmoduleswitches then
|
||||
list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG));
|
||||
list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG,nil));
|
||||
|
||||
{ MMX needs to call EMMS }
|
||||
if assigned(rg[R_MMXREGISTER]) and
|
||||
@ -247,7 +247,7 @@ unit cgcpu;
|
||||
end
|
||||
else
|
||||
list.concat(Taicpu.op_none(A_LEAVE,S_NO));
|
||||
list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG));
|
||||
list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG,nil));
|
||||
end;
|
||||
|
||||
{ return from proc }
|
||||
@ -556,7 +556,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.53 2004-09-25 14:23:54 peter
|
||||
Revision 1.54 2004-10-05 20:41:01 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.53 2004/09/25 14:23:54 peter
|
||||
* ungetregister is now only used for cpuregisters, renamed to
|
||||
ungetcpuregister
|
||||
* renamed (get|unget)explicitregister(s) to ..cpuregister
|
||||
|
@ -469,7 +469,7 @@ begin
|
||||
(taicpu(hp1).opcode = A_JMP) and
|
||||
(tasmlabel(taicpu(hp1).oper[0]^.sym) = aktexit2label)) then }
|
||||
begin
|
||||
p := tai_regalloc.deAlloc(reg);
|
||||
p := tai_regalloc.deAlloc(reg,nil);
|
||||
insertLLItem(AsmL, hp1.previous, hp1, p);
|
||||
end;
|
||||
end;
|
||||
@ -1172,13 +1172,13 @@ begin
|
||||
include(ptaiprop(p1.OptInfo)^.UsedRegs,supreg);
|
||||
if lastRemovedWasDealloc then
|
||||
begin
|
||||
hp := tai_regalloc.DeAlloc(reg);
|
||||
hp := tai_regalloc.DeAlloc(reg,nil);
|
||||
insertLLItem(asmL,p1,p1.next,hp);
|
||||
end;
|
||||
end;
|
||||
if firstRemovedWasAlloc then
|
||||
begin
|
||||
hp := tai_regalloc.Alloc(reg);
|
||||
hp := tai_regalloc.Alloc(reg,nil);
|
||||
insertLLItem(asmL,start.previous,start,hp);
|
||||
end;
|
||||
end;
|
||||
@ -2719,7 +2719,10 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.70 2004-10-04 20:46:22 peter
|
||||
Revision 1.71 2004-10-05 20:41:01 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.70 2004/10/04 20:46:22 peter
|
||||
* spilling code rewritten for x86. It now used the generic
|
||||
spilling routines. Special x86 optimization still needs
|
||||
to be added.
|
||||
|
@ -1163,7 +1163,7 @@ begin
|
||||
{ allocregbetween doesn't insert this because at }
|
||||
{ this time, no regalloc info is available in }
|
||||
{ the optinfo field, so do it manually (JM) }
|
||||
hp2 := tai_regalloc.Alloc(taicpu(hp1).oper[1]^.reg);
|
||||
hp2 := tai_regalloc.Alloc(taicpu(hp1).oper[1]^.reg,nil);
|
||||
insertllitem(asml,p.previous,p,hp2);
|
||||
taicpu(hp1).LoadReg(0,taicpu(hp1).oper[1]^.reg);
|
||||
taicpu(hp1).LoadRef(1,taicpu(p).oper[1]^.ref^);
|
||||
@ -2004,7 +2004,10 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.62 2004-10-05 17:31:41 peter
|
||||
Revision 1.63 2004-10-05 20:41:02 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.62 2004/10/05 17:31:41 peter
|
||||
* range check errors fixed
|
||||
|
||||
Revision 1.61 2004/06/20 08:55:31 florian
|
||||
|
@ -169,11 +169,12 @@ unit rgobj;
|
||||
{ can be overriden to add cpu specific interferences }
|
||||
procedure add_cpu_interferences(p : tai);virtual;
|
||||
procedure add_constraints(reg:Tregister);virtual;
|
||||
procedure getregisterinline(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister);
|
||||
procedure ungetregisterinline(list:Taasmoutput;position:Tai;r:Tregister);
|
||||
function get_spill_subreg(r : tregister) : tsubregister;virtual;
|
||||
procedure do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);virtual;
|
||||
procedure do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);virtual;
|
||||
function getregisterinline(list:Taasmoutput;subreg:Tsubregister):Tregister;
|
||||
procedure ungetregisterinline(list:Taasmoutput;r:Tregister);
|
||||
function get_spill_subreg(r : tregister) : tsubregister;virtual;
|
||||
function do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;virtual;
|
||||
procedure do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);virtual;
|
||||
procedure do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);virtual;
|
||||
|
||||
function instr_spill_register(list:Taasmoutput;
|
||||
instr:taicpu;
|
||||
@ -212,8 +213,8 @@ unit rgobj;
|
||||
procedure epilogue_colouring;
|
||||
{# Colour the registers; that is do the register allocation.}
|
||||
procedure colour_registers;
|
||||
{# Spills certain registers in the specified assembler list.}
|
||||
procedure insert_regalloc_info(list:Taasmoutput;headertai:tai);
|
||||
procedure insert_regalloc_info(list:Taasmoutput;u:tsuperregister);
|
||||
procedure insert_regalloc_info_all(list:Taasmoutput);
|
||||
procedure generate_interference_graph(list:Taasmoutput;headertai:tai);
|
||||
procedure translate_registers(list:Taasmoutput);
|
||||
function spill_registers(list:Taasmoutput;headertai:tai):boolean;virtual;
|
||||
@ -478,7 +479,7 @@ unit rgobj;
|
||||
begin
|
||||
if (getsupreg(r)>=first_imaginary) then
|
||||
InternalError(2004020901);
|
||||
list.concat(Tai_regalloc.dealloc(r));
|
||||
list.concat(Tai_regalloc.dealloc(r,nil));
|
||||
end;
|
||||
|
||||
|
||||
@ -490,7 +491,7 @@ unit rgobj;
|
||||
if supreg>=first_imaginary then
|
||||
internalerror(2003121503);
|
||||
include(used_in_proc,supreg);
|
||||
list.concat(Tai_regalloc.alloc(r));
|
||||
list.concat(Tai_regalloc.alloc(r,nil));
|
||||
end;
|
||||
|
||||
|
||||
@ -523,7 +524,7 @@ unit rgobj;
|
||||
i:Tsuperregister;
|
||||
begin
|
||||
{ Insert regalloc info for imaginary registers }
|
||||
insert_regalloc_info(list,headertai);
|
||||
insert_regalloc_info_all(list);
|
||||
ibitmap:=tinterferencebitmap.create;
|
||||
generate_interference_graph(list,headertai);
|
||||
{ Don't do the real allocation when -sr is passed }
|
||||
@ -539,6 +540,8 @@ unit rgobj;
|
||||
if spillednodes.length<>0 then
|
||||
begin
|
||||
inc(spillingcounter);
|
||||
if spillingcounter>maxspillingcounter then
|
||||
exit;
|
||||
if spillingcounter>maxspillingcounter then
|
||||
internalerror(200309041);
|
||||
endspill:=not spill_registers(list,headertai);
|
||||
@ -1370,81 +1373,80 @@ unit rgobj;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure trgobj.getregisterinline(list:Taasmoutput;
|
||||
position:Tai;subreg:Tsubregister;var result:Tregister);
|
||||
var p:Tsuperregister;
|
||||
r:Tregister;
|
||||
begin
|
||||
p:=getnewreg(subreg);
|
||||
live_registers.add(p);
|
||||
r:=newreg(regtype,p,subreg);
|
||||
if position=nil then
|
||||
list.insert(Tai_regalloc.alloc(r))
|
||||
else
|
||||
list.insertafter(Tai_regalloc.alloc(r),position);
|
||||
add_edges_used(p);
|
||||
add_constraints(r);
|
||||
result:=r;
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.ungetregisterinline(list:Taasmoutput;
|
||||
position:Tai;r:Tregister);
|
||||
|
||||
var supreg:Tsuperregister;
|
||||
|
||||
begin
|
||||
supreg:=getsupreg(r);
|
||||
live_registers.delete(supreg);
|
||||
if position=nil then
|
||||
list.insert(Tai_regalloc.dealloc(r))
|
||||
else
|
||||
list.insertafter(Tai_regalloc.dealloc(r),position);
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.insert_regalloc_info(list:Taasmoutput;headertai:tai);
|
||||
function trgobj.getregisterinline(list:Taasmoutput;subreg:Tsubregister):Tregister;
|
||||
var
|
||||
p : Tsuperregister;
|
||||
r : Tregister;
|
||||
begin
|
||||
p:=getnewreg(subreg);
|
||||
live_registers.add(p);
|
||||
result:=newreg(regtype,p,subreg);
|
||||
add_edges_used(p);
|
||||
add_constraints(result);
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.ungetregisterinline(list:Taasmoutput;r:Tregister);
|
||||
var
|
||||
supreg:Tsuperregister;
|
||||
begin
|
||||
supreg:=getsupreg(r);
|
||||
live_registers.delete(supreg);
|
||||
insert_regalloc_info(list,supreg);
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.insert_regalloc_info(list:Taasmoutput;u:tsuperregister);
|
||||
var
|
||||
supreg : tsuperregister;
|
||||
p : tai;
|
||||
r : tregister;
|
||||
begin
|
||||
{ Insert regallocs for all imaginary registers }
|
||||
with reginfo[u] do
|
||||
begin
|
||||
r:=newreg(regtype,u,subreg);
|
||||
if assigned(live_start) then
|
||||
begin
|
||||
{$ifdef EXTDEBUG}
|
||||
if live_start=live_end then
|
||||
Comment(V_Warning,'Register '+std_regname(r)+' is only used once');
|
||||
{$endif EXTDEBUG}
|
||||
list.insertbefore(Tai_regalloc.alloc(r,live_start),live_start);
|
||||
{ Insert live end deallocation before reg allocations
|
||||
to reduce conflicts }
|
||||
p:=live_end;
|
||||
while assigned(p) and
|
||||
assigned(p.previous) and
|
||||
(tai(p.previous).typ=ait_regalloc) and
|
||||
(tai_regalloc(p.previous).ratype=ra_alloc) and
|
||||
(tai_regalloc(p.previous).reg<>r) do
|
||||
p:=tai(p.previous);
|
||||
{ , but add release after sync }
|
||||
if assigned(p) and
|
||||
(p.typ=ait_regalloc) and
|
||||
(tai_regalloc(p).ratype=ra_sync) then
|
||||
p:=tai(p.next);
|
||||
if assigned(p) then
|
||||
list.insertbefore(Tai_regalloc.dealloc(r,live_end),p)
|
||||
else
|
||||
list.concat(Tai_regalloc.dealloc(r,live_end));
|
||||
end
|
||||
{$ifdef EXTDEBUG}
|
||||
else
|
||||
Comment(V_Warning,'Register '+std_regname(r)+' not used');
|
||||
{$endif EXTDEBUG}
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.insert_regalloc_info_all(list:Taasmoutput);
|
||||
var
|
||||
supreg : tsuperregister;
|
||||
begin
|
||||
{ Insert regallocs for all imaginary registers }
|
||||
for supreg:=first_imaginary to maxreg-1 do
|
||||
with reginfo[supreg] do
|
||||
begin
|
||||
r:=newreg(regtype,supreg,subreg);
|
||||
if assigned(live_start) then
|
||||
begin
|
||||
{$ifdef EXTDEBUG}
|
||||
if live_start=live_end then
|
||||
Comment(V_Warning,'Register '+std_regname(r)+' is only used once');
|
||||
{$endif EXTDEBUG}
|
||||
list.insertbefore(Tai_regalloc.alloc(r),live_start);
|
||||
{ Insert live end deallocation before reg allocations
|
||||
to reduce conflicts }
|
||||
p:=live_end;
|
||||
while assigned(p) and
|
||||
assigned(p.previous) and
|
||||
(tai(p.previous).typ=ait_regalloc) and
|
||||
(tai_regalloc(p.previous).ratype=ra_alloc) and
|
||||
(tai_regalloc(p.previous).reg<>r) do
|
||||
p:=tai(p.previous);
|
||||
{ , but add release after sync }
|
||||
if assigned(p) and
|
||||
(p.typ=ait_regalloc) and
|
||||
(tai_regalloc(p).ratype=ra_sync) then
|
||||
p:=tai(p.next);
|
||||
if assigned(p) then
|
||||
list.insertbefore(Tai_regalloc.dealloc(r),p)
|
||||
else
|
||||
list.concat(Tai_regalloc.dealloc(r));
|
||||
end
|
||||
{$ifdef EXTDEBUG}
|
||||
else
|
||||
Comment(V_Warning,'Register '+std_regname(r)+' not used');
|
||||
{$endif EXTDEBUG}
|
||||
end;
|
||||
insert_regalloc_info(list,supreg);
|
||||
end;
|
||||
|
||||
|
||||
@ -1569,6 +1571,7 @@ unit rgobj;
|
||||
ait_instruction:
|
||||
with Taicpu(p) do
|
||||
begin
|
||||
aktfilepos:=fileinfo;
|
||||
for i:=0 to ops-1 do
|
||||
with oper[i]^ do
|
||||
case typ of
|
||||
@ -1610,6 +1613,7 @@ unit rgobj;
|
||||
end;
|
||||
p:=Tai(p.next);
|
||||
end;
|
||||
aktfilepos:=current_procinfo.exitpos;
|
||||
end;
|
||||
|
||||
|
||||
@ -1702,21 +1706,21 @@ unit rgobj;
|
||||
end;
|
||||
|
||||
|
||||
procedure Trgobj.do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
|
||||
var
|
||||
helpins : Tai;
|
||||
function trgobj.do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;
|
||||
begin
|
||||
helpins:=spilling_create_load(spilltemp,tempreg);
|
||||
list.insertbefore(helpins,instr);
|
||||
result:=false;
|
||||
end;
|
||||
|
||||
|
||||
procedure Trgobj.do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
|
||||
var
|
||||
helpins : Tai;
|
||||
procedure Trgobj.do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);
|
||||
begin
|
||||
helpins:=spilling_create_store(tempreg,spilltemp);
|
||||
list.insertafter(helpins,instr);
|
||||
list.insertafter(spilling_create_load(spilltemp,tempreg),pos);
|
||||
end;
|
||||
|
||||
|
||||
procedure Trgobj.do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);
|
||||
begin
|
||||
list.insertafter(spilling_create_store(tempreg,spilltemp),pos);
|
||||
end;
|
||||
|
||||
|
||||
@ -1791,7 +1795,8 @@ unit rgobj;
|
||||
end;
|
||||
|
||||
var
|
||||
counter2 : longint;
|
||||
loadpos,
|
||||
storepos : tai;
|
||||
oldlive_registers : tsuperregisterworklist;
|
||||
begin
|
||||
result := false;
|
||||
@ -1837,42 +1842,124 @@ unit rgobj;
|
||||
if not spilled then
|
||||
exit;
|
||||
|
||||
{ Add conflicts with all non-spilled registers }
|
||||
oldlive_registers.copyfrom(live_registers);
|
||||
for counter2 := 0 to pred(regindex) do
|
||||
begin
|
||||
if (not regs[counter2].mustbespilled) then
|
||||
live_registers.add(get_alias(regs[counter2].orgreg));
|
||||
end;
|
||||
|
||||
{ generate the spilling code }
|
||||
result := true;
|
||||
{$ifdef x86}
|
||||
{ Try replacing the register with the spilltemp. This is usefull only
|
||||
for the i386,x86_64 that support memory locations for several instructions }
|
||||
for counter := 0 to pred(regindex) do
|
||||
with regs[counter] do
|
||||
begin
|
||||
if mustbespilled then
|
||||
begin
|
||||
getregisterinline(list,tai(instr.previous),get_spill_subreg(regs[counter].spillreg),tempreg);
|
||||
|
||||
if regread then
|
||||
do_spill_read(list,instr,spilltemplist[orgreg],tempreg);
|
||||
if regwritten then
|
||||
do_spill_written(list,instr,spilltemplist[orgreg],tempreg);
|
||||
if do_spill_replace(list,instr,orgreg,spilltemplist[orgreg]) then
|
||||
mustbespilled:=false;
|
||||
end;
|
||||
end;
|
||||
{$endif x86}
|
||||
|
||||
{ Release temp registers after all registers for the instruction are spilled }
|
||||
{
|
||||
There are registers that need are spilled. We generate the
|
||||
following code for it. The used positions where code need
|
||||
to be inserted are marked using #. Note that code is always inserted
|
||||
before the positions using pos.previous. This way the position is always
|
||||
the same since pos doesn't change, but pos.previous is modified everytime
|
||||
new code is inserted.
|
||||
|
||||
[
|
||||
- reg_allocs load spills
|
||||
- load spills
|
||||
]
|
||||
[#loadpos
|
||||
- reg_deallocs
|
||||
- reg_allocs
|
||||
]
|
||||
[
|
||||
- reg_deallocs for load-only spills
|
||||
- reg_allocs for store-only spills
|
||||
]
|
||||
[#instr
|
||||
- original instruction
|
||||
]
|
||||
[
|
||||
- store spills
|
||||
- reg_deallocs store spills
|
||||
]
|
||||
[#storepos
|
||||
]
|
||||
}
|
||||
|
||||
result := true;
|
||||
oldlive_registers.copyfrom(live_registers);
|
||||
|
||||
{ Process all tai_regallocs belonging to this instruction. All
|
||||
released registers are also added to the live_registers because
|
||||
they can't be used during the spilling }
|
||||
loadpos:=tai(instr.previous);
|
||||
while assigned(loadpos) and
|
||||
(loadpos.typ=ait_regalloc) and
|
||||
(tai_regalloc(loadpos).instr=instr) do
|
||||
begin
|
||||
if tai_regalloc(loadpos).ratype=ra_dealloc then
|
||||
live_registers.add(getsupreg(tai_regalloc(loadpos).reg));
|
||||
loadpos:=tai(loadpos.previous);
|
||||
end;
|
||||
loadpos:=tai(loadpos.next);
|
||||
|
||||
{ Load the spilled registers }
|
||||
for counter := 0 to pred(regindex) do
|
||||
with regs[counter] do
|
||||
begin
|
||||
if mustbespilled then
|
||||
ungetregisterinline(list,instr,tempreg);
|
||||
if mustbespilled and regread then
|
||||
begin
|
||||
tempreg:=getregisterinline(list,get_spill_subreg(regs[counter].spillreg));
|
||||
do_spill_read(list,tai(loadpos.previous),spilltemplist[orgreg],tempreg);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ restore live registers }
|
||||
{ Release temp registers of read-only registers, and add reference of the instruction
|
||||
to the reginfo }
|
||||
for counter := 0 to pred(regindex) do
|
||||
with regs[counter] do
|
||||
begin
|
||||
if mustbespilled and regread and (not regwritten) then
|
||||
begin
|
||||
{ The original instruction will be the next that uses this register }
|
||||
add_reg_instruction(instr,tempreg);
|
||||
ungetregisterinline(list,tempreg);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Allocate temp registers of write-only registers, and add reference of the instruction
|
||||
to the reginfo }
|
||||
for counter := 0 to pred(regindex) do
|
||||
with regs[counter] do
|
||||
begin
|
||||
if mustbespilled and regwritten then
|
||||
begin
|
||||
{ When the register is also loaded there is already a register assigned }
|
||||
if (not regread) then
|
||||
tempreg:=getregisterinline(list,get_spill_subreg(regs[counter].spillreg));
|
||||
{ The original instruction will be the next that uses this register, this
|
||||
also needs to be done for read-write registers }
|
||||
add_reg_instruction(instr,tempreg);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ we are now at the original instruction, restore live registers }
|
||||
live_registers.done;
|
||||
live_registers:=oldlive_registers;
|
||||
|
||||
{ store the spilled registers }
|
||||
storepos:=tai(instr.next);
|
||||
for counter := 0 to pred(regindex) do
|
||||
with regs[counter] do
|
||||
begin
|
||||
if mustbespilled and regwritten then
|
||||
begin
|
||||
do_spill_written(list,tai(storepos.previous),spilltemplist[orgreg],tempreg);
|
||||
ungetregisterinline(list,tempreg);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ substitute registers }
|
||||
for counter:=0 to instr.ops-1 do
|
||||
with instr.oper[counter]^ do
|
||||
@ -1880,12 +1967,16 @@ unit rgobj;
|
||||
case typ of
|
||||
top_reg:
|
||||
begin
|
||||
tryreplacereg(reg);
|
||||
if (getregtype(reg) = regtype) then
|
||||
tryreplacereg(reg);
|
||||
end;
|
||||
top_ref:
|
||||
begin
|
||||
tryreplacereg(ref^.base);
|
||||
tryreplacereg(ref^.index);
|
||||
if regtype in [R_INTREGISTER,R_ADDRESSREGISTER] then
|
||||
begin
|
||||
tryreplacereg(ref^.base);
|
||||
tryreplacereg(ref^.index);
|
||||
end;
|
||||
end;
|
||||
{$ifdef ARM}
|
||||
top_shifterop:
|
||||
@ -1903,7 +1994,10 @@ unit rgobj;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.138 2004-10-04 20:46:22 peter
|
||||
Revision 1.139 2004-10-05 20:41:01 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.138 2004/10/04 20:46:22 peter
|
||||
* spilling code rewritten for x86. It now used the generic
|
||||
spilling routines. Special x86 optimization still needs
|
||||
to be added.
|
||||
|
@ -162,6 +162,8 @@ implementation
|
||||
begin
|
||||
paraloc^.loc:=LOC_FPUREGISTER;
|
||||
paraloc^.register:=NR_FPU_RESULT_REG;
|
||||
if retcgsize=OS_F64 then
|
||||
setsubreg(paraloc^.register,R_SUBFD);
|
||||
paraloc^.size:=retcgsize;
|
||||
end
|
||||
else
|
||||
@ -316,7 +318,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.43 2004-09-27 21:24:17 peter
|
||||
Revision 1.44 2004-10-05 20:41:02 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.43 2004/09/27 21:24:17 peter
|
||||
* fixed passing of flaot parameters. The general size is still float,
|
||||
only the size of the locations is now OS_32
|
||||
|
||||
|
@ -78,16 +78,18 @@ implementation
|
||||
|
||||
function gas_regname(r:Tregister):string;
|
||||
var
|
||||
p : longint;
|
||||
hr : tregister;
|
||||
p : longint;
|
||||
begin
|
||||
{ Double uses the same table as single }
|
||||
case getsubreg(r) of
|
||||
hr:=r;
|
||||
case getsubreg(hr) of
|
||||
R_SUBFD:
|
||||
setsubreg(r,R_SUBFS);
|
||||
setsubreg(hr,R_SUBFS);
|
||||
R_SUBL,R_SUBW,R_SUBD,R_SUBQ:
|
||||
setsubreg(r,R_SUBD);
|
||||
setsubreg(hr,R_SUBD);
|
||||
end;
|
||||
p:=findreg_by_number(r);
|
||||
p:=findreg_by_number(hr);
|
||||
if p<>0 then
|
||||
result:=gas_regname_table[p]
|
||||
else
|
||||
@ -97,7 +99,10 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.5 2004-09-21 17:25:13 peter
|
||||
Revision 1.6 2004-10-05 20:41:02 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.5 2004/09/21 17:25:13 peter
|
||||
* paraloc branch merged
|
||||
|
||||
Revision 1.4.4.1 2004/09/20 20:42:37 peter
|
||||
|
@ -36,8 +36,8 @@ unit rgcpu;
|
||||
trgcpu=class(trgobj)
|
||||
procedure add_constraints(reg:tregister);override;
|
||||
function get_spill_subreg(r : tregister) : tsubregister;override;
|
||||
procedure do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);override;
|
||||
procedure do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);override;
|
||||
procedure do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);override;
|
||||
procedure do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);override;
|
||||
end;
|
||||
|
||||
|
||||
@ -87,7 +87,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure trgcpu.do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
|
||||
procedure trgcpu.do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);
|
||||
var
|
||||
helpins : tai;
|
||||
tmpref : treference;
|
||||
@ -115,14 +115,14 @@ implementation
|
||||
|
||||
helpins:=spilling_create_load(spilltemp,tempreg);
|
||||
helplist.concat(helpins);
|
||||
list.insertlistbefore(instr,helplist)
|
||||
list.insertlistafter(pos,helplist)
|
||||
end
|
||||
else
|
||||
inherited do_spill_read(list,instr,spilltemp,tempreg);
|
||||
inherited do_spill_read(list,pos,spilltemp,tempreg);
|
||||
end;
|
||||
|
||||
|
||||
procedure trgcpu.do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
|
||||
procedure trgcpu.do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);
|
||||
var
|
||||
helpins : tai;
|
||||
tmpref : treference;
|
||||
@ -134,7 +134,7 @@ implementation
|
||||
helplist:=taasmoutput.create;
|
||||
|
||||
if getregtype(tempreg)=R_INTREGISTER then
|
||||
getregisterinline(helplist,tai(helplist.first),R_SUBWHOLE,hreg)
|
||||
hreg:=getregisterinline(helplist,R_SUBWHOLE)
|
||||
else
|
||||
hreg:=cg.getintregister(helplist,OS_ADDR);
|
||||
|
||||
@ -151,18 +151,21 @@ implementation
|
||||
helpins:=spilling_create_store(tempreg,spilltemp);
|
||||
helplist.concat(helpins);
|
||||
if getregtype(tempreg)=R_INTREGISTER then
|
||||
ungetregisterinline(helplist,tai(helplist.last),hreg);
|
||||
ungetregisterinline(helplist,hreg);
|
||||
|
||||
list.insertlistafter(instr,helplist)
|
||||
list.insertlistafter(pos,helplist)
|
||||
end
|
||||
else
|
||||
inherited do_spill_written(list,instr,spilltemp,tempreg);
|
||||
inherited do_spill_written(list,pos,spilltemp,tempreg);
|
||||
end;
|
||||
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.28 2004-10-04 20:46:22 peter
|
||||
Revision 1.29 2004-10-05 20:41:02 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.28 2004/10/04 20:46:22 peter
|
||||
* spilling code rewritten for x86. It now used the generic
|
||||
spilling routines. Special x86 optimization still needs
|
||||
to be added.
|
||||
|
@ -1571,7 +1571,7 @@ unit cgx86;
|
||||
CGmessage(cg_d_stackframe_omited)
|
||||
else
|
||||
begin
|
||||
list.concat(tai_regalloc.alloc(NR_FRAME_POINTER_REG));
|
||||
list.concat(tai_regalloc.alloc(NR_FRAME_POINTER_REG,nil));
|
||||
include(rg[R_INTREGISTER].preserved_by_proc,RS_FRAME_POINTER_REG);
|
||||
list.concat(Taicpu.op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],NR_FRAME_POINTER_REG));
|
||||
{ Return address and FP are both on stack }
|
||||
@ -1593,7 +1593,7 @@ unit cgx86;
|
||||
begin
|
||||
a_call_name(list,'FPC_GETEIPINEBX');
|
||||
list.concat(taicpu.op_sym_ofs_reg(A_ADD,tcgsize2opsize[OS_ADDR],objectlibrary.newasmsymbol('_GLOBAL_OFFSET_TABLE_',AB_EXTERNAL,AT_DATA),0,NR_PIC_OFFSET_REG));
|
||||
list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG));
|
||||
list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG,nil));
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1675,7 +1675,10 @@ unit cgx86;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.127 2004-10-04 20:46:22 peter
|
||||
Revision 1.128 2004-10-05 20:41:02 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.127 2004/10/04 20:46:22 peter
|
||||
* spilling code rewritten for x86. It now used the generic
|
||||
spilling routines. Special x86 optimization still needs
|
||||
to be added.
|
||||
|
@ -36,21 +36,8 @@ unit rgx86;
|
||||
|
||||
type
|
||||
trgx86 = class(trgobj)
|
||||
{$ifdef OLDRGX86}
|
||||
function instr_spill_register(list:Taasmoutput;
|
||||
instr:taicpu;
|
||||
const r:Tsuperregisterset;
|
||||
const spilltemplist:Tspill_temp_list): boolean;override;
|
||||
{$endif OLDRGX86}
|
||||
function get_spill_subreg(r : tregister) : tsubregister;override;
|
||||
{
|
||||
procedure do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
|
||||
const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
|
||||
procedure do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
|
||||
const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
|
||||
procedure do_spill_readwritten(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
|
||||
const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
|
||||
}
|
||||
function get_spill_subreg(r : tregister) : tsubregister;override;
|
||||
function do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;override;
|
||||
end;
|
||||
|
||||
tpushedsavedloc = record
|
||||
@ -506,66 +493,17 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
(*
|
||||
procedure trgx86.do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
|
||||
const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
|
||||
var
|
||||
helpins: tai;
|
||||
tmpref,ref : treference;
|
||||
helplist : taasmoutput;
|
||||
tmpreg : tregister;
|
||||
function trgx86.do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;
|
||||
begin
|
||||
{ ref:=spilltemplist[regs[regidx].orgreg];
|
||||
if abs(ref.offset)>4095 then
|
||||
begin
|
||||
end
|
||||
else }
|
||||
inherited do_spill_read(list,instr,pos,regidx,spilltemplist,regs);
|
||||
result:=false;
|
||||
end;
|
||||
|
||||
|
||||
procedure trgx86.do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
|
||||
const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
|
||||
var
|
||||
helpins: tai;
|
||||
ref,tmpref : treference;
|
||||
helplist : taasmoutput;
|
||||
tmpreg : tregister;
|
||||
begin
|
||||
{ ref:=spilltemplist[regs[regidx].orgreg];
|
||||
if abs(ref.offset)>4095 then
|
||||
begin
|
||||
end
|
||||
else }
|
||||
inherited do_spill_written(list,instr,pos,regidx,spilltemplist,regs);
|
||||
end;
|
||||
|
||||
|
||||
procedure trgx86.do_spill_readwritten(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
|
||||
const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
|
||||
var
|
||||
helpins1, helpins2: tai;
|
||||
tmpref,ref : treference;
|
||||
helplist : taasmoutput;
|
||||
tmpreg : tregister;
|
||||
begin
|
||||
{ ref:=spilltemplist[regs[regidx].orgreg];
|
||||
if abs(ref.offset)>4095 then
|
||||
begin
|
||||
end
|
||||
else }
|
||||
inherited do_spill_readwritten(list,instr,pos,regidx,spilltemplist,regs);
|
||||
end;
|
||||
*)
|
||||
|
||||
{******************************************************************************
|
||||
Trgx86fpu
|
||||
******************************************************************************}
|
||||
|
||||
constructor Trgx86fpu.create;
|
||||
|
||||
var i:Tsuperregister;
|
||||
|
||||
begin
|
||||
used_in_proc:=[];
|
||||
t_times := 0;
|
||||
@ -574,7 +512,6 @@ implementation
|
||||
|
||||
|
||||
function trgx86fpu.getregisterfpu(list: taasmoutput) : tregister;
|
||||
|
||||
begin
|
||||
{ note: don't return R_ST0, see comments above implementation of }
|
||||
{ a_loadfpu_* methods in cgcpu (JM) }
|
||||
@ -583,7 +520,6 @@ implementation
|
||||
|
||||
|
||||
procedure trgx86fpu.ungetregisterfpu(list : taasmoutput; r : tregister);
|
||||
|
||||
begin
|
||||
{ nothing to do, fpu stack management is handled by the load/ }
|
||||
{ store operations in cgcpu (JM) }
|
||||
@ -592,7 +528,6 @@ implementation
|
||||
|
||||
|
||||
function trgx86fpu.correct_fpuregister(r : tregister;ofs : byte) : tregister;
|
||||
|
||||
begin
|
||||
correct_fpuregister:=r;
|
||||
setsupreg(correct_fpuregister,ofs);
|
||||
@ -690,7 +625,10 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.7 2004-10-04 20:46:22 peter
|
||||
Revision 1.8 2004-10-05 20:41:02 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.7 2004/10/04 20:46:22 peter
|
||||
* spilling code rewritten for x86. It now used the generic
|
||||
spilling routines. Special x86 optimization still needs
|
||||
to be added.
|
||||
|
@ -82,7 +82,7 @@ unit cgcpu;
|
||||
begin
|
||||
{ Release PIC register }
|
||||
if cs_create_pic in aktmoduleswitches then
|
||||
list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG));
|
||||
list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG,nil));
|
||||
|
||||
{ remove stackframe }
|
||||
if not nostackframe then
|
||||
@ -95,7 +95,7 @@ unit cgcpu;
|
||||
end
|
||||
else
|
||||
list.concat(Taicpu.op_none(A_LEAVE,S_NO));
|
||||
list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG));
|
||||
list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG,nil));
|
||||
end;
|
||||
|
||||
list.concat(Taicpu.Op_none(A_RET,S_NO));
|
||||
@ -109,7 +109,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.16 2004-09-21 17:25:13 peter
|
||||
Revision 1.17 2004-10-05 20:41:02 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.16 2004/09/21 17:25:13 peter
|
||||
* paraloc branch merged
|
||||
|
||||
Revision 1.15.4.1 2004/08/31 20:43:06 peter
|
||||
|
Loading…
Reference in New Issue
Block a user