* more spilling rewrites

This commit is contained in:
peter 2004-10-05 20:41:01 +00:00
parent feeba0ede6
commit f5471aef6e
12 changed files with 296 additions and 224 deletions

View File

@ -487,8 +487,12 @@ interface
tai_regalloc = class(tai) tai_regalloc = class(tai)
reg : tregister; reg : tregister;
ratype : TRegAllocType; ratype : TRegAllocType;
constructor alloc(r : tregister); { reg(de)alloc belongs to this instruction, this
constructor dealloc(r : tregister); 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 sync(r : tregister);
constructor resize(r : tregister); constructor resize(r : tregister);
constructor ppuload(t:taitype;ppufile:tcompilerppufile);override; constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
@ -1717,21 +1721,23 @@ implementation
tai_regalloc tai_regalloc
*****************************************************************************} *****************************************************************************}
constructor tai_regalloc.alloc(r : tregister); constructor tai_regalloc.alloc(r : tregister;ainstr:tai);
begin begin
inherited create; inherited create;
typ:=ait_regalloc; typ:=ait_regalloc;
ratype:=ra_alloc; ratype:=ra_alloc;
reg:=r; reg:=r;
instr:=ainstr;
end; end;
constructor tai_regalloc.dealloc(r : tregister); constructor tai_regalloc.dealloc(r : tregister;ainstr:tai);
begin begin
inherited create; inherited create;
typ:=ait_regalloc; typ:=ait_regalloc;
ratype:=ra_dealloc; ratype:=ra_dealloc;
reg:=r; reg:=r;
instr:=ainstr;
end; end;
@ -2224,7 +2230,10 @@ begin
end. end.
{ {
$Log$ $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 * simple regvar support, not yet finished
Revision 1.88 2004/08/15 13:30:18 florian Revision 1.88 2004/08/15 13:30:18 florian

View File

@ -708,13 +708,13 @@ implementation
procedure tcg.a_reg_alloc(list : taasmoutput;r : tregister); procedure tcg.a_reg_alloc(list : taasmoutput;r : tregister);
begin begin
list.concat(tai_regalloc.alloc(r)); list.concat(tai_regalloc.alloc(r,nil));
end; end;
procedure tcg.a_reg_dealloc(list : taasmoutput;r : tregister); procedure tcg.a_reg_dealloc(list : taasmoutput;r : tregister);
begin begin
list.concat(tai_regalloc.dealloc(r)); list.concat(tai_regalloc.dealloc(r,nil));
end; end;
@ -2226,7 +2226,10 @@ finalization
end. end.
{ {
$Log$ $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 more sparc overflow stuff
* fixed some op64 stuff for sparc * fixed some op64 stuff for sparc

View File

@ -229,7 +229,7 @@ unit cgcpu;
begin begin
{ Release PIC register } { Release PIC register }
if cs_create_pic in aktmoduleswitches then 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 } { MMX needs to call EMMS }
if assigned(rg[R_MMXREGISTER]) and if assigned(rg[R_MMXREGISTER]) and
@ -247,7 +247,7 @@ unit cgcpu;
end end
else else
list.concat(Taicpu.op_none(A_LEAVE,S_NO)); 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; end;
{ return from proc } { return from proc }
@ -556,7 +556,10 @@ begin
end. end.
{ {
$Log$ $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 * ungetregister is now only used for cpuregisters, renamed to
ungetcpuregister ungetcpuregister
* renamed (get|unget)explicitregister(s) to ..cpuregister * renamed (get|unget)explicitregister(s) to ..cpuregister

View File

@ -469,7 +469,7 @@ begin
(taicpu(hp1).opcode = A_JMP) and (taicpu(hp1).opcode = A_JMP) and
(tasmlabel(taicpu(hp1).oper[0]^.sym) = aktexit2label)) then } (tasmlabel(taicpu(hp1).oper[0]^.sym) = aktexit2label)) then }
begin begin
p := tai_regalloc.deAlloc(reg); p := tai_regalloc.deAlloc(reg,nil);
insertLLItem(AsmL, hp1.previous, hp1, p); insertLLItem(AsmL, hp1.previous, hp1, p);
end; end;
end; end;
@ -1172,13 +1172,13 @@ begin
include(ptaiprop(p1.OptInfo)^.UsedRegs,supreg); include(ptaiprop(p1.OptInfo)^.UsedRegs,supreg);
if lastRemovedWasDealloc then if lastRemovedWasDealloc then
begin begin
hp := tai_regalloc.DeAlloc(reg); hp := tai_regalloc.DeAlloc(reg,nil);
insertLLItem(asmL,p1,p1.next,hp); insertLLItem(asmL,p1,p1.next,hp);
end; end;
end; end;
if firstRemovedWasAlloc then if firstRemovedWasAlloc then
begin begin
hp := tai_regalloc.Alloc(reg); hp := tai_regalloc.Alloc(reg,nil);
insertLLItem(asmL,start.previous,start,hp); insertLLItem(asmL,start.previous,start,hp);
end; end;
end; end;
@ -2719,7 +2719,10 @@ end.
{ {
$Log$ $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 code rewritten for x86. It now used the generic
spilling routines. Special x86 optimization still needs spilling routines. Special x86 optimization still needs
to be added. to be added.

View File

@ -1163,7 +1163,7 @@ begin
{ allocregbetween doesn't insert this because at } { allocregbetween doesn't insert this because at }
{ this time, no regalloc info is available in } { this time, no regalloc info is available in }
{ the optinfo field, so do it manually (JM) } { 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); insertllitem(asml,p.previous,p,hp2);
taicpu(hp1).LoadReg(0,taicpu(hp1).oper[1]^.reg); taicpu(hp1).LoadReg(0,taicpu(hp1).oper[1]^.reg);
taicpu(hp1).LoadRef(1,taicpu(p).oper[1]^.ref^); taicpu(hp1).LoadRef(1,taicpu(p).oper[1]^.ref^);
@ -2004,7 +2004,10 @@ end.
{ {
$Log$ $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 * range check errors fixed
Revision 1.61 2004/06/20 08:55:31 florian Revision 1.61 2004/06/20 08:55:31 florian

View File

@ -169,11 +169,12 @@ unit rgobj;
{ can be overriden to add cpu specific interferences } { can be overriden to add cpu specific interferences }
procedure add_cpu_interferences(p : tai);virtual; procedure add_cpu_interferences(p : tai);virtual;
procedure add_constraints(reg:Tregister);virtual; procedure add_constraints(reg:Tregister);virtual;
procedure getregisterinline(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister); function getregisterinline(list:Taasmoutput;subreg:Tsubregister):Tregister;
procedure ungetregisterinline(list:Taasmoutput;position:Tai;r:Tregister); procedure ungetregisterinline(list:Taasmoutput;r:Tregister);
function get_spill_subreg(r : tregister) : tsubregister;virtual; function get_spill_subreg(r : tregister) : tsubregister;virtual;
procedure do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);virtual; function do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;virtual;
procedure do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);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; function instr_spill_register(list:Taasmoutput;
instr:taicpu; instr:taicpu;
@ -212,8 +213,8 @@ unit rgobj;
procedure epilogue_colouring; procedure epilogue_colouring;
{# Colour the registers; that is do the register allocation.} {# Colour the registers; that is do the register allocation.}
procedure colour_registers; procedure colour_registers;
{# Spills certain registers in the specified assembler list.} procedure insert_regalloc_info(list:Taasmoutput;u:tsuperregister);
procedure insert_regalloc_info(list:Taasmoutput;headertai:tai); procedure insert_regalloc_info_all(list:Taasmoutput);
procedure generate_interference_graph(list:Taasmoutput;headertai:tai); procedure generate_interference_graph(list:Taasmoutput;headertai:tai);
procedure translate_registers(list:Taasmoutput); procedure translate_registers(list:Taasmoutput);
function spill_registers(list:Taasmoutput;headertai:tai):boolean;virtual; function spill_registers(list:Taasmoutput;headertai:tai):boolean;virtual;
@ -478,7 +479,7 @@ unit rgobj;
begin begin
if (getsupreg(r)>=first_imaginary) then if (getsupreg(r)>=first_imaginary) then
InternalError(2004020901); InternalError(2004020901);
list.concat(Tai_regalloc.dealloc(r)); list.concat(Tai_regalloc.dealloc(r,nil));
end; end;
@ -490,7 +491,7 @@ unit rgobj;
if supreg>=first_imaginary then if supreg>=first_imaginary then
internalerror(2003121503); internalerror(2003121503);
include(used_in_proc,supreg); include(used_in_proc,supreg);
list.concat(Tai_regalloc.alloc(r)); list.concat(Tai_regalloc.alloc(r,nil));
end; end;
@ -523,7 +524,7 @@ unit rgobj;
i:Tsuperregister; i:Tsuperregister;
begin begin
{ Insert regalloc info for imaginary registers } { Insert regalloc info for imaginary registers }
insert_regalloc_info(list,headertai); insert_regalloc_info_all(list);
ibitmap:=tinterferencebitmap.create; ibitmap:=tinterferencebitmap.create;
generate_interference_graph(list,headertai); generate_interference_graph(list,headertai);
{ Don't do the real allocation when -sr is passed } { Don't do the real allocation when -sr is passed }
@ -539,6 +540,8 @@ unit rgobj;
if spillednodes.length<>0 then if spillednodes.length<>0 then
begin begin
inc(spillingcounter); inc(spillingcounter);
if spillingcounter>maxspillingcounter then
exit;
if spillingcounter>maxspillingcounter then if spillingcounter>maxspillingcounter then
internalerror(200309041); internalerror(200309041);
endspill:=not spill_registers(list,headertai); endspill:=not spill_registers(list,headertai);
@ -1370,57 +1373,46 @@ unit rgobj;
end; end;
end; end;
procedure trgobj.getregisterinline(list:Taasmoutput;
position:Tai;subreg:Tsubregister;var result:Tregister); function trgobj.getregisterinline(list:Taasmoutput;subreg:Tsubregister):Tregister;
var p:Tsuperregister; var
p : Tsuperregister;
r : Tregister; r : Tregister;
begin begin
p:=getnewreg(subreg); p:=getnewreg(subreg);
live_registers.add(p); live_registers.add(p);
r:=newreg(regtype,p,subreg); result:=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_edges_used(p);
add_constraints(r); add_constraints(result);
result:=r;
end; end;
procedure trgobj.ungetregisterinline(list:Taasmoutput; procedure trgobj.ungetregisterinline(list:Taasmoutput;r:Tregister);
position:Tai;r:Tregister); var
supreg:Tsuperregister;
var supreg:Tsuperregister;
begin begin
supreg:=getsupreg(r); supreg:=getsupreg(r);
live_registers.delete(supreg); live_registers.delete(supreg);
if position=nil then insert_regalloc_info(list,supreg);
list.insert(Tai_regalloc.dealloc(r))
else
list.insertafter(Tai_regalloc.dealloc(r),position);
end; end;
procedure trgobj.insert_regalloc_info(list:Taasmoutput;headertai:tai); procedure trgobj.insert_regalloc_info(list:Taasmoutput;u:tsuperregister);
var var
supreg : tsuperregister;
p : tai; p : tai;
r : tregister; r : tregister;
begin begin
{ Insert regallocs for all imaginary registers } { Insert regallocs for all imaginary registers }
for supreg:=first_imaginary to maxreg-1 do with reginfo[u] do
with reginfo[supreg] do
begin begin
r:=newreg(regtype,supreg,subreg); r:=newreg(regtype,u,subreg);
if assigned(live_start) then if assigned(live_start) then
begin begin
{$ifdef EXTDEBUG} {$ifdef EXTDEBUG}
if live_start=live_end then if live_start=live_end then
Comment(V_Warning,'Register '+std_regname(r)+' is only used once'); Comment(V_Warning,'Register '+std_regname(r)+' is only used once');
{$endif EXTDEBUG} {$endif EXTDEBUG}
list.insertbefore(Tai_regalloc.alloc(r),live_start); list.insertbefore(Tai_regalloc.alloc(r,live_start),live_start);
{ Insert live end deallocation before reg allocations { Insert live end deallocation before reg allocations
to reduce conflicts } to reduce conflicts }
p:=live_end; p:=live_end;
@ -1436,9 +1428,9 @@ unit rgobj;
(tai_regalloc(p).ratype=ra_sync) then (tai_regalloc(p).ratype=ra_sync) then
p:=tai(p.next); p:=tai(p.next);
if assigned(p) then if assigned(p) then
list.insertbefore(Tai_regalloc.dealloc(r),p) list.insertbefore(Tai_regalloc.dealloc(r,live_end),p)
else else
list.concat(Tai_regalloc.dealloc(r)); list.concat(Tai_regalloc.dealloc(r,live_end));
end end
{$ifdef EXTDEBUG} {$ifdef EXTDEBUG}
else else
@ -1448,6 +1440,16 @@ unit rgobj;
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
insert_regalloc_info(list,supreg);
end;
procedure trgobj.add_cpu_interferences(p : tai); procedure trgobj.add_cpu_interferences(p : tai);
begin begin
end; end;
@ -1569,6 +1571,7 @@ unit rgobj;
ait_instruction: ait_instruction:
with Taicpu(p) do with Taicpu(p) do
begin begin
aktfilepos:=fileinfo;
for i:=0 to ops-1 do for i:=0 to ops-1 do
with oper[i]^ do with oper[i]^ do
case typ of case typ of
@ -1610,6 +1613,7 @@ unit rgobj;
end; end;
p:=Tai(p.next); p:=Tai(p.next);
end; end;
aktfilepos:=current_procinfo.exitpos;
end; end;
@ -1702,21 +1706,21 @@ unit rgobj;
end; end;
procedure Trgobj.do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister); function trgobj.do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;
var
helpins : Tai;
begin begin
helpins:=spilling_create_load(spilltemp,tempreg); result:=false;
list.insertbefore(helpins,instr);
end; end;
procedure Trgobj.do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister); procedure Trgobj.do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);
var
helpins : Tai;
begin begin
helpins:=spilling_create_store(tempreg,spilltemp); list.insertafter(spilling_create_load(spilltemp,tempreg),pos);
list.insertafter(helpins,instr); 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; end;
@ -1791,7 +1795,8 @@ unit rgobj;
end; end;
var var
counter2 : longint; loadpos,
storepos : tai;
oldlive_registers : tsuperregisterworklist; oldlive_registers : tsuperregisterworklist;
begin begin
result := false; result := false;
@ -1837,42 +1842,124 @@ unit rgobj;
if not spilled then if not spilled then
exit; exit;
{ Add conflicts with all non-spilled registers } {$ifdef x86}
oldlive_registers.copyfrom(live_registers); { Try replacing the register with the spilltemp. This is usefull only
for counter2 := 0 to pred(regindex) do for the i386,x86_64 that support memory locations for several instructions }
for counter := 0 to pred(regindex) do
with regs[counter] do
begin begin
if (not regs[counter2].mustbespilled) then if mustbespilled then
live_registers.add(get_alias(regs[counter2].orgreg)); begin
if do_spill_replace(list,instr,orgreg,spilltemplist[orgreg]) then
mustbespilled:=false;
end; end;
end;
{$endif x86}
{
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
]
}
{ generate the spilling code }
result := true; 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 for counter := 0 to pred(regindex) do
with regs[counter] do with regs[counter] do
begin begin
if mustbespilled then if mustbespilled and regread then
begin begin
getregisterinline(list,tai(instr.previous),get_spill_subreg(regs[counter].spillreg),tempreg); tempreg:=getregisterinline(list,get_spill_subreg(regs[counter].spillreg));
do_spill_read(list,tai(loadpos.previous),spilltemplist[orgreg],tempreg);
if regread then
do_spill_read(list,instr,spilltemplist[orgreg],tempreg);
if regwritten then
do_spill_written(list,instr,spilltemplist[orgreg],tempreg);
end; end;
end; end;
{ Release temp registers after all registers for the instruction are spilled } { Release temp registers of read-only registers, and add reference of the instruction
to the reginfo }
for counter := 0 to pred(regindex) do for counter := 0 to pred(regindex) do
with regs[counter] do with regs[counter] do
begin begin
if mustbespilled then if mustbespilled and regread and (not regwritten) then
ungetregisterinline(list,instr,tempreg); begin
{ The original instruction will be the next that uses this register }
add_reg_instruction(instr,tempreg);
ungetregisterinline(list,tempreg);
end;
end; end;
{ restore live registers } { 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.done;
live_registers:=oldlive_registers; 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 } { substitute registers }
for counter:=0 to instr.ops-1 do for counter:=0 to instr.ops-1 do
with instr.oper[counter]^ do with instr.oper[counter]^ do
@ -1880,13 +1967,17 @@ unit rgobj;
case typ of case typ of
top_reg: top_reg:
begin begin
if (getregtype(reg) = regtype) then
tryreplacereg(reg); tryreplacereg(reg);
end; end;
top_ref: top_ref:
begin
if regtype in [R_INTREGISTER,R_ADDRESSREGISTER] then
begin begin
tryreplacereg(ref^.base); tryreplacereg(ref^.base);
tryreplacereg(ref^.index); tryreplacereg(ref^.index);
end; end;
end;
{$ifdef ARM} {$ifdef ARM}
top_shifterop: top_shifterop:
begin begin
@ -1903,7 +1994,10 @@ unit rgobj;
end. end.
{ {
$Log$ $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 code rewritten for x86. It now used the generic
spilling routines. Special x86 optimization still needs spilling routines. Special x86 optimization still needs
to be added. to be added.

View File

@ -162,6 +162,8 @@ implementation
begin begin
paraloc^.loc:=LOC_FPUREGISTER; paraloc^.loc:=LOC_FPUREGISTER;
paraloc^.register:=NR_FPU_RESULT_REG; paraloc^.register:=NR_FPU_RESULT_REG;
if retcgsize=OS_F64 then
setsubreg(paraloc^.register,R_SUBFD);
paraloc^.size:=retcgsize; paraloc^.size:=retcgsize;
end end
else else
@ -316,7 +318,10 @@ begin
end. end.
{ {
$Log$ $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, * fixed passing of flaot parameters. The general size is still float,
only the size of the locations is now OS_32 only the size of the locations is now OS_32

View File

@ -78,16 +78,18 @@ implementation
function gas_regname(r:Tregister):string; function gas_regname(r:Tregister):string;
var var
hr : tregister;
p : longint; p : longint;
begin begin
{ Double uses the same table as single } { Double uses the same table as single }
case getsubreg(r) of hr:=r;
case getsubreg(hr) of
R_SUBFD: R_SUBFD:
setsubreg(r,R_SUBFS); setsubreg(hr,R_SUBFS);
R_SUBL,R_SUBW,R_SUBD,R_SUBQ: R_SUBL,R_SUBW,R_SUBD,R_SUBQ:
setsubreg(r,R_SUBD); setsubreg(hr,R_SUBD);
end; end;
p:=findreg_by_number(r); p:=findreg_by_number(hr);
if p<>0 then if p<>0 then
result:=gas_regname_table[p] result:=gas_regname_table[p]
else else
@ -97,7 +99,10 @@ implementation
end. end.
{ {
$Log$ $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 * paraloc branch merged
Revision 1.4.4.1 2004/09/20 20:42:37 peter Revision 1.4.4.1 2004/09/20 20:42:37 peter

View File

@ -36,8 +36,8 @@ unit rgcpu;
trgcpu=class(trgobj) trgcpu=class(trgobj)
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;
procedure do_spill_read(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;instr:taicpu;const spilltemp:treference;const tempreg:tregister);override; procedure do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);override;
end; end;
@ -87,7 +87,7 @@ implementation
end; 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 var
helpins : tai; helpins : tai;
tmpref : treference; tmpref : treference;
@ -115,14 +115,14 @@ implementation
helpins:=spilling_create_load(spilltemp,tempreg); helpins:=spilling_create_load(spilltemp,tempreg);
helplist.concat(helpins); helplist.concat(helpins);
list.insertlistbefore(instr,helplist) list.insertlistafter(pos,helplist)
end end
else else
inherited do_spill_read(list,instr,spilltemp,tempreg); inherited do_spill_read(list,pos,spilltemp,tempreg);
end; 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 var
helpins : tai; helpins : tai;
tmpref : treference; tmpref : treference;
@ -134,7 +134,7 @@ implementation
helplist:=taasmoutput.create; helplist:=taasmoutput.create;
if getregtype(tempreg)=R_INTREGISTER then if getregtype(tempreg)=R_INTREGISTER then
getregisterinline(helplist,tai(helplist.first),R_SUBWHOLE,hreg) hreg:=getregisterinline(helplist,R_SUBWHOLE)
else else
hreg:=cg.getintregister(helplist,OS_ADDR); hreg:=cg.getintregister(helplist,OS_ADDR);
@ -151,18 +151,21 @@ implementation
helpins:=spilling_create_store(tempreg,spilltemp); helpins:=spilling_create_store(tempreg,spilltemp);
helplist.concat(helpins); helplist.concat(helpins);
if getregtype(tempreg)=R_INTREGISTER then if getregtype(tempreg)=R_INTREGISTER then
ungetregisterinline(helplist,tai(helplist.last),hreg); ungetregisterinline(helplist,hreg);
list.insertlistafter(instr,helplist) list.insertlistafter(pos,helplist)
end end
else else
inherited do_spill_written(list,instr,spilltemp,tempreg); inherited do_spill_written(list,pos,spilltemp,tempreg);
end; end;
end. end.
{ {
$Log$ $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 code rewritten for x86. It now used the generic
spilling routines. Special x86 optimization still needs spilling routines. Special x86 optimization still needs
to be added. to be added.

View File

@ -1571,7 +1571,7 @@ unit cgx86;
CGmessage(cg_d_stackframe_omited) CGmessage(cg_d_stackframe_omited)
else else
begin 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); 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)); list.concat(Taicpu.op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],NR_FRAME_POINTER_REG));
{ Return address and FP are both on stack } { Return address and FP are both on stack }
@ -1593,7 +1593,7 @@ unit cgx86;
begin begin
a_call_name(list,'FPC_GETEIPINEBX'); 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(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;
end; end;
@ -1675,7 +1675,10 @@ unit cgx86;
end. end.
{ {
$Log$ $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 code rewritten for x86. It now used the generic
spilling routines. Special x86 optimization still needs spilling routines. Special x86 optimization still needs
to be added. to be added.

View File

@ -36,21 +36,8 @@ unit rgx86;
type type
trgx86 = class(trgobj) 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; function get_spill_subreg(r : tregister) : tsubregister;override;
{ function do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;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;
}
end; end;
tpushedsavedloc = record tpushedsavedloc = record
@ -506,66 +493,17 @@ implementation
end; end;
(* function trgx86.do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;
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;
begin begin
{ ref:=spilltemplist[regs[regidx].orgreg]; result:=false;
if abs(ref.offset)>4095 then
begin
end
else }
inherited do_spill_read(list,instr,pos,regidx,spilltemplist,regs);
end; 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 Trgx86fpu
******************************************************************************} ******************************************************************************}
constructor Trgx86fpu.create; constructor Trgx86fpu.create;
var i:Tsuperregister;
begin begin
used_in_proc:=[]; used_in_proc:=[];
t_times := 0; t_times := 0;
@ -574,7 +512,6 @@ implementation
function trgx86fpu.getregisterfpu(list: taasmoutput) : tregister; function trgx86fpu.getregisterfpu(list: taasmoutput) : tregister;
begin begin
{ note: don't return R_ST0, see comments above implementation of } { note: don't return R_ST0, see comments above implementation of }
{ a_loadfpu_* methods in cgcpu (JM) } { a_loadfpu_* methods in cgcpu (JM) }
@ -583,7 +520,6 @@ implementation
procedure trgx86fpu.ungetregisterfpu(list : taasmoutput; r : tregister); procedure trgx86fpu.ungetregisterfpu(list : taasmoutput; r : tregister);
begin begin
{ nothing to do, fpu stack management is handled by the load/ } { nothing to do, fpu stack management is handled by the load/ }
{ store operations in cgcpu (JM) } { store operations in cgcpu (JM) }
@ -592,7 +528,6 @@ implementation
function trgx86fpu.correct_fpuregister(r : tregister;ofs : byte) : tregister; function trgx86fpu.correct_fpuregister(r : tregister;ofs : byte) : tregister;
begin begin
correct_fpuregister:=r; correct_fpuregister:=r;
setsupreg(correct_fpuregister,ofs); setsupreg(correct_fpuregister,ofs);
@ -690,7 +625,10 @@ implementation
end. end.
{ {
$Log$ $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 code rewritten for x86. It now used the generic
spilling routines. Special x86 optimization still needs spilling routines. Special x86 optimization still needs
to be added. to be added.

View File

@ -82,7 +82,7 @@ unit cgcpu;
begin begin
{ Release PIC register } { Release PIC register }
if cs_create_pic in aktmoduleswitches then 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 } { remove stackframe }
if not nostackframe then if not nostackframe then
@ -95,7 +95,7 @@ unit cgcpu;
end end
else else
list.concat(Taicpu.op_none(A_LEAVE,S_NO)); 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; end;
list.concat(Taicpu.Op_none(A_RET,S_NO)); list.concat(Taicpu.Op_none(A_RET,S_NO));
@ -109,7 +109,10 @@ begin
end. end.
{ {
$Log$ $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 * paraloc branch merged
Revision 1.15.4.1 2004/08/31 20:43:06 peter Revision 1.15.4.1 2004/08/31 20:43:06 peter