mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 22:49:17 +02:00
* spilling code rewritten for x86. It now used the generic
spilling routines. Special x86 optimization still needs to be added. * Spilling fixed when both operands needed to be spilled * Cleanup of spilling routine, do_spill_readwritten removed
This commit is contained in:
parent
ec720a5800
commit
ee3585f56f
@ -140,7 +140,7 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
for opCount := 1 to MaxCh do
|
for opCount := 1 to maxinschanges do
|
||||||
case InsProp[p.opcode].Ch[opCount] of
|
case InsProp[p.opcode].Ch[opCount] of
|
||||||
Ch_MOp1,CH_WOp1,CH_RWOp1:
|
Ch_MOp1,CH_WOp1,CH_RWOp1:
|
||||||
if not(onlymem) or
|
if not(onlymem) or
|
||||||
@ -904,7 +904,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
NoHardCodedRegs := true;
|
NoHardCodedRegs := true;
|
||||||
with InsProp[p.opcode] do
|
with InsProp[p.opcode] do
|
||||||
for chCount := 1 to MaxCh do
|
for chCount := 1 to maxinschanges do
|
||||||
if Ch[chCount] in ([Ch_REAX..Ch_MEDI,Ch_WMemEDI,Ch_All]-[Ch_RESP,Ch_WESP,Ch_RWESP]) then
|
if Ch[chCount] in ([Ch_REAX..Ch_MEDI,Ch_WMemEDI,Ch_All]-[Ch_RESP,Ch_WESP,Ch_RWESP]) then
|
||||||
begin
|
begin
|
||||||
NoHardCodedRegs := false;
|
NoHardCodedRegs := false;
|
||||||
@ -1058,7 +1058,7 @@ begin
|
|||||||
{ updateStates(orgReg,newReg,p,false);}
|
{ updateStates(orgReg,newReg,p,false);}
|
||||||
doReplaceReadReg := true;
|
doReplaceReadReg := true;
|
||||||
end;
|
end;
|
||||||
for opCount := 1 to MaxCh do
|
for opCount := 1 to maxinschanges do
|
||||||
case InsProp[p.opcode].Ch[opCount] of
|
case InsProp[p.opcode].Ch[opCount] of
|
||||||
Ch_ROp1:
|
Ch_ROp1:
|
||||||
if p.oper[0]^.typ = top_reg then
|
if p.oper[0]^.typ = top_reg then
|
||||||
@ -1901,7 +1901,7 @@ begin
|
|||||||
ptaiprop(tai(p).optinfo)^.CanBeRemoved := True;
|
ptaiprop(tai(p).optinfo)^.CanBeRemoved := True;
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
for cnt := 1 to maxch do
|
for cnt := 1 to maxinschanges do
|
||||||
begin
|
begin
|
||||||
case InsProp[taicpu(p).opcode].Ch[cnt] of
|
case InsProp[taicpu(p).opcode].Ch[cnt] of
|
||||||
Ch_ROp1:
|
Ch_ROp1:
|
||||||
@ -2109,7 +2109,14 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.65 2004-09-21 17:25:12 peter
|
Revision 1.66 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.
|
||||||
|
* Spilling fixed when both operands needed to be spilled
|
||||||
|
* Cleanup of spilling routine, do_spill_readwritten removed
|
||||||
|
|
||||||
|
Revision 1.65 2004/09/21 17:25:12 peter
|
||||||
* paraloc branch merged
|
* paraloc branch merged
|
||||||
|
|
||||||
Revision 1.64.4.1 2004/09/20 19:28:23 peter
|
Revision 1.64.4.1 2004/09/20 19:28:23 peter
|
||||||
|
@ -725,7 +725,7 @@ begin
|
|||||||
RegReadByInstruction := true;
|
RegReadByInstruction := true;
|
||||||
exit
|
exit
|
||||||
end;
|
end;
|
||||||
for opcount := 1 to maxch do
|
for opcount := 1 to maxinschanges do
|
||||||
case insprop[p.opcode].ch[opcount] of
|
case insprop[p.opcode].ch[opcount] of
|
||||||
CH_REAX..CH_REDI,CH_RWEAX..CH_MEDI:
|
CH_REAX..CH_REDI,CH_RWEAX..CH_MEDI:
|
||||||
if supreg = tch2reg(insprop[p.opcode].ch[opcount]) then
|
if supreg = tch2reg(insprop[p.opcode].ch[opcount]) then
|
||||||
@ -791,7 +791,7 @@ begin
|
|||||||
(supreg in [RS_EAX,RS_EDX])
|
(supreg in [RS_EAX,RS_EDX])
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
for opcount := 1 to MaxCh do
|
for opcount := 1 to maxinschanges do
|
||||||
case insprop[p.opcode].Ch[opCount] of
|
case insprop[p.opcode].Ch[opCount] of
|
||||||
CH_REAX..CH_MEDI:
|
CH_REAX..CH_MEDI:
|
||||||
if tch2reg(InsProp[p.opcode].Ch[opCount]) = supreg then
|
if tch2reg(InsProp[p.opcode].Ch[opCount]) = supreg then
|
||||||
@ -866,7 +866,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
Cnt := 1;
|
Cnt := 1;
|
||||||
InstrProp := InsProp[taicpu(p1).OpCode];
|
InstrProp := InsProp[taicpu(p1).OpCode];
|
||||||
while (Cnt <= MaxCh) and
|
while (Cnt <= maxinschanges) and
|
||||||
(InstrProp.Ch[Cnt] <> Ch_None) and
|
(InstrProp.Ch[Cnt] <> Ch_None) and
|
||||||
not(TmpResult) Do
|
not(TmpResult) Do
|
||||||
begin
|
begin
|
||||||
@ -901,7 +901,7 @@ begin
|
|||||||
case p.typ of
|
case p.typ of
|
||||||
ait_instruction:
|
ait_instruction:
|
||||||
begin
|
begin
|
||||||
for l := 1 to MaxCh do
|
for l := 1 to maxinschanges do
|
||||||
if InsProp[taicpu(p).opcode].Ch[l] in [Ch_WFlags,Ch_RWFlags,Ch_All] then
|
if InsProp[taicpu(p).opcode].Ch[l] in [Ch_WFlags,Ch_RWFlags,Ch_All] then
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -920,7 +920,7 @@ begin
|
|||||||
case p.typ of
|
case p.typ of
|
||||||
ait_instruction:
|
ait_instruction:
|
||||||
begin
|
begin
|
||||||
for l := 1 to MaxCh do
|
for l := 1 to maxinschanges do
|
||||||
if InsProp[taicpu(p).opcode].Ch[l] in [Ch_RFlags,Ch_RWFlags,Ch_All] then
|
if InsProp[taicpu(p).opcode].Ch[l] in [Ch_RFlags,Ch_RWFlags,Ch_All] then
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -2555,7 +2555,7 @@ begin
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
Cnt := 1;
|
Cnt := 1;
|
||||||
while (Cnt <= MaxCh) and
|
while (Cnt <= maxinschanges) and
|
||||||
(InstrProp.Ch[Cnt] <> Ch_None) Do
|
(InstrProp.Ch[Cnt] <> Ch_None) Do
|
||||||
begin
|
begin
|
||||||
case InstrProp.Ch[Cnt] Of
|
case InstrProp.Ch[Cnt] Of
|
||||||
@ -2719,7 +2719,14 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.69 2004-09-26 17:45:30 peter
|
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.
|
||||||
|
* Spilling fixed when both operands needed to be spilled
|
||||||
|
* Cleanup of spilling routine, do_spill_readwritten removed
|
||||||
|
|
||||||
|
Revision 1.69 2004/09/26 17:45:30 peter
|
||||||
* simple regvar support, not yet finished
|
* simple regvar support, not yet finished
|
||||||
|
|
||||||
Revision 1.68 2004/06/20 08:55:31 florian
|
Revision 1.68 2004/06/20 08:55:31 florian
|
||||||
|
@ -28,49 +28,6 @@ unit optbase;
|
|||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses cpuinfo, cpubase;
|
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
|
||||||
Opcode propeties (needed for optimizer)
|
|
||||||
*****************************************************************************}
|
|
||||||
|
|
||||||
{$ifndef NOOPT}
|
|
||||||
Type
|
|
||||||
{What an instruction can change}
|
|
||||||
TInsChange = (Ch_None,
|
|
||||||
{Read from a register}
|
|
||||||
Ch_REAX, Ch_RECX, Ch_REDX, Ch_REBX, Ch_RESP, Ch_REBP, Ch_RESI, Ch_REDI,
|
|
||||||
{write from a register}
|
|
||||||
Ch_WEAX, Ch_WECX, Ch_WEDX, Ch_WEBX, Ch_WESP, Ch_WEBP, Ch_WESI, Ch_WEDI,
|
|
||||||
{read and write from/to a register}
|
|
||||||
Ch_RWEAX, Ch_RWECX, Ch_RWEDX, Ch_RWEBX, Ch_RWESP, Ch_RWEBP, Ch_RWESI, Ch_RWEDI,
|
|
||||||
{modify the contents of a register with the purpose of using
|
|
||||||
this changed content afterwards (add/sub/..., but e.g. not rep
|
|
||||||
or movsd)}
|
|
||||||
Ch_MEAX, Ch_MECX, Ch_MEDX, Ch_MEBX, Ch_MESP, Ch_MEBP, Ch_MESI, Ch_MEDI,
|
|
||||||
Ch_CDirFlag {clear direction flag}, Ch_SDirFlag {set dir flag},
|
|
||||||
Ch_RFlags, Ch_WFlags, Ch_RWFlags, Ch_FPU,
|
|
||||||
Ch_Rop1, Ch_Wop1, Ch_RWop1,Ch_Mop1,
|
|
||||||
Ch_Rop2, Ch_Wop2, Ch_RWop2,Ch_Mop2,
|
|
||||||
Ch_Rop3, Ch_WOp3, Ch_RWOp3,Ch_Mop3,
|
|
||||||
Ch_WMemEDI,
|
|
||||||
Ch_All
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
const
|
|
||||||
MaxCh = 3; { Max things a instruction can change }
|
|
||||||
type
|
|
||||||
TInsProp = packed record
|
|
||||||
Ch : Array[1..MaxCh] of TInsChange;
|
|
||||||
end;
|
|
||||||
|
|
||||||
const
|
|
||||||
InsProp : array[tasmop] of TInsProp =
|
|
||||||
{$i i386prop.inc}
|
|
||||||
|
|
||||||
{$endif NOOPT}
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -79,7 +36,14 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.3 2004-06-20 08:55:31 florian
|
Revision 1.4 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.
|
||||||
|
* Spilling fixed when both operands needed to be spilled
|
||||||
|
* Cleanup of spilling routine, do_spill_readwritten removed
|
||||||
|
|
||||||
|
Revision 1.3 2004/06/20 08:55:31 florian
|
||||||
* logs truncated
|
* logs truncated
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -135,8 +135,6 @@ unit rgobj;
|
|||||||
trgobj=class
|
trgobj=class
|
||||||
preserved_by_proc : tcpuregisterset;
|
preserved_by_proc : tcpuregisterset;
|
||||||
used_in_proc : tcpuregisterset;
|
used_in_proc : tcpuregisterset;
|
||||||
// is_reg_var : Tsuperregisterset; {old regvars}
|
|
||||||
// reg_var_loaded:Tsuperregisterset; {old regvars}
|
|
||||||
|
|
||||||
constructor create(Aregtype:Tregistertype;
|
constructor create(Aregtype:Tregistertype;
|
||||||
Adefaultsub:Tsubregister;
|
Adefaultsub:Tsubregister;
|
||||||
@ -170,25 +168,12 @@ unit rgobj;
|
|||||||
live_registers:Tsuperregisterworklist;
|
live_registers:Tsuperregisterworklist;
|
||||||
{ 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;
|
||||||
function get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister):Tai;
|
procedure add_constraints(reg:Tregister);virtual;
|
||||||
procedure forward_allocation(pfrom,pto:Tai);
|
|
||||||
procedure getregisterinline(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister);
|
procedure getregisterinline(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister);
|
||||||
procedure ungetregisterinline(list:Taasmoutput;position:Tai;r:Tregister);
|
procedure ungetregisterinline(list:Taasmoutput;position:Tai;r:Tregister);
|
||||||
procedure add_constraints(reg:Tregister);virtual;
|
|
||||||
|
|
||||||
function get_spill_subreg(r : tregister) : tsubregister;virtual;
|
function get_spill_subreg(r : tregister) : tsubregister;virtual;
|
||||||
procedure do_spill_read(list:Taasmoutput;instr:Taicpu;
|
procedure do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);virtual;
|
||||||
pos:Tai;regidx:word;
|
procedure do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);virtual;
|
||||||
const spilltemplist:Tspill_temp_list;
|
|
||||||
const regs:Tspillregsinfo);virtual;
|
|
||||||
procedure do_spill_written(list:Taasmoutput;instr:Taicpu;
|
|
||||||
pos:Tai;regidx:word;
|
|
||||||
const spilltemplist:Tspill_temp_list;
|
|
||||||
const regs:Tspillregsinfo);virtual;
|
|
||||||
procedure do_spill_readwritten(list:Taasmoutput;instr:Taicpu;
|
|
||||||
pos:Tai;regidx:word;
|
|
||||||
const spilltemplist:Tspill_temp_list;
|
|
||||||
const regs:Tspillregsinfo);virtual;
|
|
||||||
|
|
||||||
function instr_spill_register(list:Taasmoutput;
|
function instr_spill_register(list:Taasmoutput;
|
||||||
instr:taicpu;
|
instr:taicpu;
|
||||||
@ -603,22 +588,12 @@ unit rgobj;
|
|||||||
procedure trgobj.add_edges_used(u:Tsuperregister);
|
procedure trgobj.add_edges_used(u:Tsuperregister);
|
||||||
|
|
||||||
var i:word;
|
var i:word;
|
||||||
v:tsuperregister;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
with live_registers do
|
with live_registers do
|
||||||
if length>0 then
|
if length>0 then
|
||||||
for i:=0 to length-1 do
|
for i:=0 to length-1 do
|
||||||
begin
|
add_edge(u,get_alias(buf^[i]));
|
||||||
v:=buf^[i];
|
|
||||||
add_edge(u,v);
|
|
||||||
{ add also conflicts with all coalesced registers }
|
|
||||||
while ri_coalesced in reginfo[v].flags do
|
|
||||||
begin
|
|
||||||
v:=reginfo[v].alias;
|
|
||||||
add_edge(u,v);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$ifdef EXTDEBUG}
|
{$ifdef EXTDEBUG}
|
||||||
@ -1638,69 +1613,6 @@ unit rgobj;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function trgobj.get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister):Tai;
|
|
||||||
var
|
|
||||||
back : Tsuperregisterworklist;
|
|
||||||
supreg : tsuperregister;
|
|
||||||
begin
|
|
||||||
back.copyfrom(live_registers);
|
|
||||||
result:=p;
|
|
||||||
while (p<>nil) and (p.typ=ait_regalloc) do
|
|
||||||
begin
|
|
||||||
supreg:=getsupreg(Tai_regalloc(p).reg);
|
|
||||||
{Rewind the register allocation.}
|
|
||||||
if (Tai_regalloc(p).ratype=ra_alloc) then
|
|
||||||
live_registers.delete(supreg)
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
live_registers.add(supreg);
|
|
||||||
if supreg=huntfor1 then
|
|
||||||
begin
|
|
||||||
get_insert_pos:=Tai(p.previous);
|
|
||||||
back.done;
|
|
||||||
back.copyfrom(live_registers);
|
|
||||||
end;
|
|
||||||
if supreg=huntfor2 then
|
|
||||||
begin
|
|
||||||
get_insert_pos:=Tai(p.previous);
|
|
||||||
back.done;
|
|
||||||
back.copyfrom(live_registers);
|
|
||||||
end;
|
|
||||||
if supreg=huntfor3 then
|
|
||||||
begin
|
|
||||||
get_insert_pos:=Tai(p.previous);
|
|
||||||
back.done;
|
|
||||||
back.copyfrom(live_registers);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
p:=Tai(p.previous);
|
|
||||||
end;
|
|
||||||
live_registers.done;
|
|
||||||
live_registers:=back;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure trgobj.forward_allocation(pfrom,pto:Tai);
|
|
||||||
var
|
|
||||||
p : tai;
|
|
||||||
begin
|
|
||||||
{Forward the register allocation again.}
|
|
||||||
p:=pfrom;
|
|
||||||
while (p<>pto) do
|
|
||||||
begin
|
|
||||||
if p.typ<>ait_regalloc then
|
|
||||||
internalerror(200305311);
|
|
||||||
case Tai_regalloc(p).ratype of
|
|
||||||
ra_alloc :
|
|
||||||
live_registers.add(getsupreg(Tai_regalloc(p).reg));
|
|
||||||
ra_dealloc :
|
|
||||||
live_registers.delete(getsupreg(Tai_regalloc(p).reg));
|
|
||||||
end;
|
|
||||||
p:=Tai(p.next);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function trgobj.spill_registers(list:Taasmoutput;headertai:tai):boolean;
|
function trgobj.spill_registers(list:Taasmoutput;headertai:tai):boolean;
|
||||||
{ Returns true if any help registers have been used }
|
{ Returns true if any help registers have been used }
|
||||||
var
|
var
|
||||||
@ -1790,64 +1702,21 @@ unit rgobj;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure Trgobj.do_spill_read(list:Taasmoutput;instr:taicpu;
|
procedure Trgobj.do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
|
||||||
pos:Tai;regidx:word;
|
var
|
||||||
const spilltemplist:Tspill_temp_list;
|
helpins : Tai;
|
||||||
const regs:Tspillregsinfo);
|
|
||||||
|
|
||||||
var helpins:Tai;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
with regs[regidx] do
|
helpins:=spilling_create_load(spilltemp,tempreg);
|
||||||
begin
|
list.insertbefore(helpins,instr);
|
||||||
helpins:=spilling_create_load(spilltemplist[orgreg],tempreg);
|
|
||||||
if pos=nil then
|
|
||||||
list.insertafter(helpins,list.first)
|
|
||||||
else
|
|
||||||
list.insertafter(helpins,pos.next);
|
|
||||||
ungetregisterinline(list,instr,tempreg);
|
|
||||||
forward_allocation(tai(helpins.next),instr);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure Trgobj.do_spill_written(list:Taasmoutput;instr:taicpu;
|
procedure Trgobj.do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
|
||||||
pos:Tai;regidx:word;
|
var
|
||||||
const spilltemplist:Tspill_temp_list;
|
helpins : Tai;
|
||||||
const regs:Tspillregsinfo);
|
|
||||||
|
|
||||||
var helpins:Tai;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
with regs[regidx] do
|
helpins:=spilling_create_store(tempreg,spilltemp);
|
||||||
begin
|
|
||||||
helpins:=spilling_create_store(tempreg,spilltemplist[orgreg]);
|
|
||||||
list.insertafter(helpins,instr);
|
list.insertafter(helpins,instr);
|
||||||
ungetregisterinline(list,helpins,tempreg);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure Trgobj.do_spill_readwritten(list:Taasmoutput;instr:taicpu;
|
|
||||||
pos:Tai;regidx:word;
|
|
||||||
const spilltemplist:Tspill_temp_list;
|
|
||||||
const regs:Tspillregsinfo);
|
|
||||||
|
|
||||||
var helpins1,helpins2:Tai;
|
|
||||||
|
|
||||||
begin
|
|
||||||
with regs[regidx] do
|
|
||||||
begin
|
|
||||||
helpins1:=spilling_create_load(spilltemplist[orgreg],tempreg);
|
|
||||||
if pos=nil then
|
|
||||||
list.insertafter(helpins1,list.first)
|
|
||||||
else
|
|
||||||
list.insertafter(helpins1,pos.next);
|
|
||||||
helpins2:=spilling_create_store(tempreg,spilltemplist[orgreg]);
|
|
||||||
list.insertafter(helpins2,instr);
|
|
||||||
ungetregisterinline(list,helpins2,tempreg);
|
|
||||||
forward_allocation(tai(helpins1.next),instr);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1863,7 +1732,6 @@ unit rgobj;
|
|||||||
const spilltemplist:Tspill_temp_list): boolean;
|
const spilltemplist:Tspill_temp_list): boolean;
|
||||||
var
|
var
|
||||||
counter, regindex: longint;
|
counter, regindex: longint;
|
||||||
pos: tai;
|
|
||||||
regs: tspillregsinfo;
|
regs: tspillregsinfo;
|
||||||
spilled: boolean;
|
spilled: boolean;
|
||||||
|
|
||||||
@ -1874,7 +1742,7 @@ unit rgobj;
|
|||||||
begin
|
begin
|
||||||
tmpindex := regindex;
|
tmpindex := regindex;
|
||||||
supreg:=getsupreg(reg);
|
supreg:=getsupreg(reg);
|
||||||
// did we already encounter this register?
|
{ did we already encounter this register? }
|
||||||
for i := 0 to pred(regindex) do
|
for i := 0 to pred(regindex) do
|
||||||
if (regs[i].orgreg = supreg) then
|
if (regs[i].orgreg = supreg) then
|
||||||
begin
|
begin
|
||||||
@ -1887,7 +1755,7 @@ unit rgobj;
|
|||||||
regs[tmpindex].spillreg:=reg;
|
regs[tmpindex].spillreg:=reg;
|
||||||
if supregset_in(r,supreg) then
|
if supregset_in(r,supreg) then
|
||||||
begin
|
begin
|
||||||
// add/update info on this register
|
{ add/update info on this register }
|
||||||
regs[tmpindex].mustbespilled := true;
|
regs[tmpindex].mustbespilled := true;
|
||||||
case operation of
|
case operation of
|
||||||
operand_read:
|
operand_read:
|
||||||
@ -1916,12 +1784,15 @@ unit rgobj;
|
|||||||
if (regs[i].mustbespilled) and
|
if (regs[i].mustbespilled) and
|
||||||
(regs[i].orgreg=supreg) then
|
(regs[i].orgreg=supreg) then
|
||||||
begin
|
begin
|
||||||
reg:=regs[i].tempreg;
|
{ Only replace supreg }
|
||||||
|
setsupreg(reg,getsupreg(regs[i].tempreg));
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
counter2 : longint;
|
||||||
|
oldlive_registers : tsuperregisterworklist;
|
||||||
begin
|
begin
|
||||||
result := false;
|
result := false;
|
||||||
fillchar(regs,sizeof(regs),0);
|
fillchar(regs,sizeof(regs),0);
|
||||||
@ -1966,6 +1837,14 @@ unit rgobj;
|
|||||||
if not spilled then
|
if not spilled then
|
||||||
exit;
|
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 }
|
{ generate the spilling code }
|
||||||
result := true;
|
result := true;
|
||||||
for counter := 0 to pred(regindex) do
|
for counter := 0 to pred(regindex) do
|
||||||
@ -1973,18 +1852,27 @@ unit rgobj;
|
|||||||
begin
|
begin
|
||||||
if mustbespilled then
|
if mustbespilled then
|
||||||
begin
|
begin
|
||||||
pos:=get_insert_pos(Tai(instr.previous),regs[0].orgreg,regs[1].orgreg,regs[2].orgreg);
|
getregisterinline(list,tai(instr.previous),get_spill_subreg(regs[counter].spillreg),tempreg);
|
||||||
getregisterinline(list,pos,get_spill_subreg(regs[counter].spillreg),tempreg);
|
|
||||||
if regread then
|
if regread then
|
||||||
|
do_spill_read(list,instr,spilltemplist[orgreg],tempreg);
|
||||||
if regwritten then
|
if regwritten then
|
||||||
do_spill_readwritten(list,instr,pos,counter,spilltemplist,regs)
|
do_spill_written(list,instr,spilltemplist[orgreg],tempreg);
|
||||||
else
|
|
||||||
do_spill_read(list,instr,pos,counter,spilltemplist,regs)
|
|
||||||
else
|
|
||||||
do_spill_written(list,instr,pos,counter,spilltemplist,regs)
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ Release temp registers after all registers for the instruction are spilled }
|
||||||
|
for counter := 0 to pred(regindex) do
|
||||||
|
with regs[counter] do
|
||||||
|
begin
|
||||||
|
if mustbespilled then
|
||||||
|
ungetregisterinline(list,instr,tempreg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ restore live registers }
|
||||||
|
live_registers.done;
|
||||||
|
live_registers:=oldlive_registers;
|
||||||
|
|
||||||
{ 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
|
||||||
@ -2015,7 +1903,14 @@ unit rgobj;
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.137 2004-09-26 17:45:30 peter
|
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.
|
||||||
|
* Spilling fixed when both operands needed to be spilled
|
||||||
|
* Cleanup of spilling routine, do_spill_readwritten removed
|
||||||
|
|
||||||
|
Revision 1.137 2004/09/26 17:45:30 peter
|
||||||
* simple regvar support, not yet finished
|
* simple regvar support, not yet finished
|
||||||
|
|
||||||
Revision 1.136 2004/09/25 14:23:54 peter
|
Revision 1.136 2004/09/25 14:23:54 peter
|
||||||
|
@ -36,12 +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;pos: tai; regidx: word;
|
procedure do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);override;
|
||||||
const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
|
procedure do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);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;
|
||||||
|
|
||||||
|
|
||||||
@ -91,159 +87,89 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure trgcpu.do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
|
procedure trgcpu.do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
|
||||||
const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
|
|
||||||
var
|
var
|
||||||
helpins : tai;
|
helpins : tai;
|
||||||
tmpref,ref : treference;
|
tmpref : treference;
|
||||||
helplist : taasmoutput;
|
helplist : taasmoutput;
|
||||||
tmpreg : tregister;
|
hreg : tregister;
|
||||||
begin
|
begin
|
||||||
ref:=spilltemplist[regs[regidx].orgreg];
|
if abs(spilltemp.offset)>4095 then
|
||||||
if abs(ref.offset)>4095 then
|
|
||||||
begin
|
begin
|
||||||
helplist:=taasmoutput.create;
|
helplist:=taasmoutput.create;
|
||||||
reference_reset(tmpref);
|
|
||||||
|
|
||||||
if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
|
if getregtype(tempreg)=R_INTREGISTER then
|
||||||
getregisterinline(helplist,nil,defaultsub,tmpreg)
|
hreg:=tempreg
|
||||||
else
|
else
|
||||||
tmpreg:=cg.getintregister(helplist,OS_ADDR);
|
hreg:=cg.getintregister(helplist,OS_ADDR);
|
||||||
|
|
||||||
tmpref.offset:=ref.offset;
|
reference_reset(tmpref);
|
||||||
|
tmpref.offset:=spilltemp.offset;
|
||||||
tmpref.refaddr:=addr_hi;
|
tmpref.refaddr:=addr_hi;
|
||||||
helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,tmpreg));
|
helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,hreg));
|
||||||
|
|
||||||
tmpref.refaddr:=addr_lo;
|
tmpref.refaddr:=addr_lo;
|
||||||
helplist.concat(taicpu.op_reg_ref_reg(A_OR,tmpreg,tmpref,tmpreg));
|
helplist.concat(taicpu.op_reg_ref_reg(A_OR,hreg,tmpref,hreg));
|
||||||
|
|
||||||
if ref.index<>NR_NO then
|
reference_reset_base(tmpref,hreg,0);
|
||||||
internalerror(200401263);
|
|
||||||
ref.index:=tmpreg;
|
|
||||||
ref.offset:=0;
|
|
||||||
|
|
||||||
helpins:=spilling_create_load(ref,regs[regidx].tempreg);
|
helpins:=spilling_create_load(spilltemp,tempreg);
|
||||||
helplist.concat(helpins);
|
helplist.concat(helpins);
|
||||||
if pos=nil then
|
list.insertlistbefore(instr,helplist)
|
||||||
list.insertlistafter(list.first,helplist)
|
|
||||||
else
|
|
||||||
list.insertlistafter(pos.next,helplist);
|
|
||||||
helplist.free;
|
|
||||||
|
|
||||||
ungetregisterinline(list,helpins,regs[regidx].tempreg);
|
|
||||||
|
|
||||||
if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
|
|
||||||
ungetregisterinline(list,helpins,tmpreg);
|
|
||||||
|
|
||||||
forward_allocation(tai(helpins.next),instr);
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
inherited do_spill_read(list,instr,pos,regidx,spilltemplist,regs);
|
inherited do_spill_read(list,instr,spilltemp,tempreg);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure trgcpu.do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
|
procedure trgcpu.do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
|
||||||
const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
|
|
||||||
var
|
var
|
||||||
helpins : tai;
|
helpins : tai;
|
||||||
ref,tmpref : treference;
|
tmpref : treference;
|
||||||
helplist : taasmoutput;
|
helplist : taasmoutput;
|
||||||
tmpreg : tregister;
|
hreg : tregister;
|
||||||
begin
|
begin
|
||||||
ref:=spilltemplist[regs[regidx].orgreg];
|
if abs(spilltemp.offset)>4095 then
|
||||||
if abs(ref.offset)>4095 then
|
|
||||||
begin
|
begin
|
||||||
helplist:=taasmoutput.create;
|
helplist:=taasmoutput.create;
|
||||||
reference_reset(tmpref);
|
|
||||||
|
|
||||||
if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
|
if getregtype(tempreg)=R_INTREGISTER then
|
||||||
getregisterinline(helplist,pos,defaultsub,tmpreg)
|
getregisterinline(helplist,tai(helplist.first),R_SUBWHOLE,hreg)
|
||||||
else
|
else
|
||||||
tmpreg:=cg.getintregister(helplist,OS_ADDR);
|
hreg:=cg.getintregister(helplist,OS_ADDR);
|
||||||
|
|
||||||
tmpref.offset:=ref.offset;
|
reference_reset(tmpref);
|
||||||
|
tmpref.offset:=spilltemp.offset;
|
||||||
tmpref.refaddr:=addr_hi;
|
tmpref.refaddr:=addr_hi;
|
||||||
helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,tmpreg));
|
helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,hreg));
|
||||||
|
|
||||||
tmpref.refaddr:=addr_lo;
|
tmpref.refaddr:=addr_lo;
|
||||||
helplist.concat(taicpu.op_reg_ref_reg(A_OR,tmpreg,tmpref,tmpreg));
|
helplist.concat(taicpu.op_reg_ref_reg(A_OR,hreg,tmpref,hreg));
|
||||||
|
|
||||||
if ref.index<>NR_NO then
|
reference_reset_base(tmpref,hreg,0);
|
||||||
internalerror(200401263);
|
|
||||||
ref.index:=tmpreg;
|
|
||||||
ref.offset:=0;
|
|
||||||
|
|
||||||
helpins:=spilling_create_store(regs[regidx].tempreg,ref);
|
helpins:=spilling_create_store(tempreg,spilltemp);
|
||||||
helplist.concat(helpins);
|
helplist.concat(helpins);
|
||||||
list.insertlistafter(instr,helplist);
|
if getregtype(tempreg)=R_INTREGISTER then
|
||||||
helplist.free;
|
ungetregisterinline(helplist,tai(helplist.last),hreg);
|
||||||
|
|
||||||
ungetregisterinline(list,helpins,regs[regidx].tempreg);
|
list.insertlistafter(instr,helplist)
|
||||||
|
|
||||||
if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
|
|
||||||
ungetregisterinline(list,helpins,tmpreg);
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
inherited do_spill_written(list,instr,pos,regidx,spilltemplist,regs);
|
inherited do_spill_written(list,instr,spilltemp,tempreg);
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure trgcpu.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
|
|
||||||
helplist:=taasmoutput.create;
|
|
||||||
reference_reset(tmpref);
|
|
||||||
|
|
||||||
if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
|
|
||||||
getregisterinline(helplist,nil,defaultsub,tmpreg)
|
|
||||||
else
|
|
||||||
tmpreg:=cg.getintregister(helplist,OS_ADDR);
|
|
||||||
|
|
||||||
tmpref.offset:=ref.offset;
|
|
||||||
tmpref.refaddr:=addr_hi;
|
|
||||||
helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,tmpreg));
|
|
||||||
|
|
||||||
tmpref.refaddr:=addr_lo;
|
|
||||||
helplist.concat(taicpu.op_reg_ref_reg(A_OR,tmpreg,tmpref,tmpreg));
|
|
||||||
|
|
||||||
if ref.index<>NR_NO then
|
|
||||||
internalerror(200401263);
|
|
||||||
ref.index:=tmpreg;
|
|
||||||
ref.offset:=0;
|
|
||||||
|
|
||||||
helpins1:=spilling_create_load(ref,regs[regidx].tempreg);
|
|
||||||
helplist.concat(helpins1);
|
|
||||||
if pos=nil then
|
|
||||||
list.insertlistafter(list.first,helplist)
|
|
||||||
else
|
|
||||||
list.insertlistafter(pos.next,helplist);
|
|
||||||
helplist.free;
|
|
||||||
|
|
||||||
helpins2:=spilling_create_store(regs[regidx].tempreg,ref);
|
|
||||||
list.insertafter(helpins2,instr);
|
|
||||||
ungetregisterinline(list,helpins2,regs[regidx].tempreg);
|
|
||||||
|
|
||||||
if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
|
|
||||||
ungetregisterinline(list,helpins2,tmpreg);
|
|
||||||
|
|
||||||
forward_allocation(tai(helpins1.next),instr);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
inherited do_spill_readwritten(list,instr,pos,regidx,spilltemplist,regs);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.27 2004-10-01 17:33:47 peter
|
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.
|
||||||
|
* Spilling fixed when both operands needed to be spilled
|
||||||
|
* Cleanup of spilling routine, do_spill_readwritten removed
|
||||||
|
|
||||||
|
Revision 1.27 2004/10/01 17:33:47 peter
|
||||||
* indents
|
* indents
|
||||||
|
|
||||||
Revision 1.26 2004/09/28 20:19:36 peter
|
Revision 1.26 2004/09/28 20:19:36 peter
|
||||||
|
@ -130,6 +130,36 @@ interface
|
|||||||
instabentries = {$i i386nop.inc}
|
instabentries = {$i i386nop.inc}
|
||||||
{$endif x86_64}
|
{$endif x86_64}
|
||||||
maxinfolen = 8;
|
maxinfolen = 8;
|
||||||
|
MaxInsChanges = 3; { Max things a instruction can change }
|
||||||
|
|
||||||
|
type
|
||||||
|
{ What an instruction can change. Needed for optimizer and spilling code }
|
||||||
|
TInsChange = (Ch_None,
|
||||||
|
{Read from a register}
|
||||||
|
Ch_REAX, Ch_RECX, Ch_REDX, Ch_REBX, Ch_RESP, Ch_REBP, Ch_RESI, Ch_REDI,
|
||||||
|
{write from a register}
|
||||||
|
Ch_WEAX, Ch_WECX, Ch_WEDX, Ch_WEBX, Ch_WESP, Ch_WEBP, Ch_WESI, Ch_WEDI,
|
||||||
|
{read and write from/to a register}
|
||||||
|
Ch_RWEAX, Ch_RWECX, Ch_RWEDX, Ch_RWEBX, Ch_RWESP, Ch_RWEBP, Ch_RWESI, Ch_RWEDI,
|
||||||
|
{modify the contents of a register with the purpose of using
|
||||||
|
this changed content afterwards (add/sub/..., but e.g. not rep
|
||||||
|
or movsd)}
|
||||||
|
Ch_MEAX, Ch_MECX, Ch_MEDX, Ch_MEBX, Ch_MESP, Ch_MEBP, Ch_MESI, Ch_MEDI,
|
||||||
|
Ch_CDirFlag {clear direction flag}, Ch_SDirFlag {set dir flag},
|
||||||
|
Ch_RFlags, Ch_WFlags, Ch_RWFlags, Ch_FPU,
|
||||||
|
Ch_Rop1, Ch_Wop1, Ch_RWop1,Ch_Mop1,
|
||||||
|
Ch_Rop2, Ch_Wop2, Ch_RWop2,Ch_Mop2,
|
||||||
|
Ch_Rop3, Ch_WOp3, Ch_RWOp3,Ch_Mop3,
|
||||||
|
Ch_WMemEDI,
|
||||||
|
Ch_All
|
||||||
|
);
|
||||||
|
|
||||||
|
TInsProp = packed record
|
||||||
|
Ch : Array[1..MaxInsChanges] of TInsChange;
|
||||||
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
InsProp : array[tasmop] of TInsProp = {$i i386prop.inc}
|
||||||
|
|
||||||
type
|
type
|
||||||
TOperandOrder = (op_intel,op_att);
|
TOperandOrder = (op_intel,op_att);
|
||||||
@ -201,6 +231,8 @@ interface
|
|||||||
procedure Pass2(objdata:TAsmObjectdata);virtual;
|
procedure Pass2(objdata:TAsmObjectdata);virtual;
|
||||||
procedure SetOperandOrder(order:TOperandOrder);
|
procedure SetOperandOrder(order:TOperandOrder);
|
||||||
function is_same_reg_move(regtype: Tregistertype):boolean;override;
|
function is_same_reg_move(regtype: Tregistertype):boolean;override;
|
||||||
|
{ register spilling code }
|
||||||
|
function spilling_get_operation_type(opnr: longint): topertype;override;
|
||||||
protected
|
protected
|
||||||
procedure ppuloadoper(ppufile:tcompilerppufile;var o:toper);override;
|
procedure ppuloadoper(ppufile:tcompilerppufile;var o:toper);override;
|
||||||
procedure ppuwriteoper(ppufile:tcompilerppufile;const o:toper);override;
|
procedure ppuwriteoper(ppufile:tcompilerppufile;const o:toper);override;
|
||||||
@ -366,6 +398,12 @@ implementation
|
|||||||
);
|
);
|
||||||
{$endif x86_64}
|
{$endif x86_64}
|
||||||
|
|
||||||
|
{ Operation type for spilling code }
|
||||||
|
type
|
||||||
|
toperation_type_table=array[tasmop,0..Max_Operands] of topertype;
|
||||||
|
var
|
||||||
|
operation_type_table : ^toperation_type_table;
|
||||||
|
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
TAI_ALIGN
|
TAI_ALIGN
|
||||||
@ -1932,15 +1970,74 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure build_spilling_operation_type_table;
|
||||||
|
var
|
||||||
|
opcode : tasmop;
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
new(operation_type_table);
|
||||||
|
fillchar(operation_type_table^,sizeof(toperation_type_table),byte(operand_read));
|
||||||
|
for opcode:=low(tasmop) to high(tasmop) do
|
||||||
|
begin
|
||||||
|
for i:=1 to MaxInsChanges do
|
||||||
|
begin
|
||||||
|
case InsProp[opcode].Ch[i] of
|
||||||
|
Ch_Rop1 :
|
||||||
|
operation_type_table^[opcode,0]:=operand_read;
|
||||||
|
Ch_Wop1 :
|
||||||
|
operation_type_table^[opcode,0]:=operand_write;
|
||||||
|
Ch_RWop1,
|
||||||
|
Ch_Mop1 :
|
||||||
|
operation_type_table^[opcode,0]:=operand_readwrite;
|
||||||
|
Ch_Rop2 :
|
||||||
|
operation_type_table^[opcode,1]:=operand_read;
|
||||||
|
Ch_Wop2 :
|
||||||
|
operation_type_table^[opcode,1]:=operand_write;
|
||||||
|
Ch_RWop2,
|
||||||
|
Ch_Mop2 :
|
||||||
|
operation_type_table^[opcode,1]:=operand_readwrite;
|
||||||
|
Ch_Rop3 :
|
||||||
|
operation_type_table^[opcode,2]:=operand_read;
|
||||||
|
Ch_Wop3 :
|
||||||
|
operation_type_table^[opcode,2]:=operand_write;
|
||||||
|
Ch_RWop3,
|
||||||
|
Ch_Mop3 :
|
||||||
|
operation_type_table^[opcode,2]:=operand_readwrite;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function taicpu.spilling_get_operation_type(opnr: longint): topertype;
|
||||||
|
begin
|
||||||
|
result:=operation_type_table^[opcode,opnr];
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function spilling_create_load(const ref:treference;r:tregister): tai;
|
function spilling_create_load(const ref:treference;r:tregister): tai;
|
||||||
begin
|
begin
|
||||||
internalerror(200406131);
|
case getregtype(r) of
|
||||||
|
R_INTREGISTER :
|
||||||
|
result:=taicpu.op_ref_reg(A_MOV,reg2opsize(r),ref,r);
|
||||||
|
R_MMREGISTER :
|
||||||
|
result:=taicpu.op_ref_reg(A_MOVSD,reg2opsize(r),ref,r);
|
||||||
|
else
|
||||||
|
internalerror(200401041);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function spilling_create_store(r:tregister; const ref:treference): tai;
|
function spilling_create_store(r:tregister; const ref:treference): tai;
|
||||||
begin
|
begin
|
||||||
internalerror(200406132);
|
case getregtype(r) of
|
||||||
|
R_INTREGISTER :
|
||||||
|
result:=taicpu.op_reg_ref(A_MOV,reg2opsize(r),r,ref);
|
||||||
|
R_MMREGISTER :
|
||||||
|
result:=taicpu.op_reg_ref(A_MOVSD,reg2opsize(r),r,ref);
|
||||||
|
else
|
||||||
|
internalerror(200401041);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1970,6 +2067,7 @@ implementation
|
|||||||
|
|
||||||
procedure InitAsm;
|
procedure InitAsm;
|
||||||
begin
|
begin
|
||||||
|
build_spilling_operation_type_table;
|
||||||
{$ifndef NOAG386BIN}
|
{$ifndef NOAG386BIN}
|
||||||
if not assigned(instabcache) then
|
if not assigned(instabcache) then
|
||||||
BuildInsTabCache;
|
BuildInsTabCache;
|
||||||
@ -1979,6 +2077,11 @@ implementation
|
|||||||
|
|
||||||
procedure DoneAsm;
|
procedure DoneAsm;
|
||||||
begin
|
begin
|
||||||
|
if assigned(operation_type_table) then
|
||||||
|
begin
|
||||||
|
dispose(operation_type_table);
|
||||||
|
operation_type_table:=nil;
|
||||||
|
end;
|
||||||
{$ifndef NOAG386BIN}
|
{$ifndef NOAG386BIN}
|
||||||
if assigned(instabcache) then
|
if assigned(instabcache) then
|
||||||
begin
|
begin
|
||||||
@ -1995,7 +2098,14 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.58 2004-09-27 15:12:47 peter
|
Revision 1.59 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.
|
||||||
|
* Spilling fixed when both operands needed to be spilled
|
||||||
|
* Cleanup of spilling routine, do_spill_readwritten removed
|
||||||
|
|
||||||
|
Revision 1.58 2004/09/27 15:12:47 peter
|
||||||
* IE when expecting top_ref
|
* IE when expecting top_ref
|
||||||
|
|
||||||
Revision 1.57 2004/06/20 08:55:32 florian
|
Revision 1.57 2004/06/20 08:55:32 florian
|
||||||
|
@ -551,12 +551,15 @@ unit cgx86;
|
|||||||
if s in [S_BL,S_WL,S_L] then
|
if s in [S_BL,S_WL,S_L] then
|
||||||
reg2:=makeregsize(list,reg2,OS_32);
|
reg2:=makeregsize(list,reg2,OS_32);
|
||||||
{$endif x86_64}
|
{$endif x86_64}
|
||||||
|
if (reg1<>reg2) then
|
||||||
|
begin
|
||||||
instr:=taicpu.op_reg_reg(op,s,reg1,reg2);
|
instr:=taicpu.op_reg_reg(op,s,reg1,reg2);
|
||||||
{ Notify the register allocator that we have written a move instruction so
|
{ Notify the register allocator that we have written a move instruction so
|
||||||
it can try to eliminate it. }
|
it can try to eliminate it. }
|
||||||
add_move_instruction(instr);
|
add_move_instruction(instr);
|
||||||
list.concat(instr);
|
list.concat(instr);
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcgx86.a_loadaddr_ref_reg(list : taasmoutput;const ref : treference;r : tregister);
|
procedure tcgx86.a_loadaddr_ref_reg(list : taasmoutput;const ref : treference;r : tregister);
|
||||||
@ -1672,7 +1675,14 @@ unit cgx86;
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.126 2004-10-03 12:42:22 florian
|
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.
|
||||||
|
* Spilling fixed when both operands needed to be spilled
|
||||||
|
* Cleanup of spilling routine, do_spill_readwritten removed
|
||||||
|
|
||||||
|
Revision 1.126 2004/10/03 12:42:22 florian
|
||||||
* made sqrt, sqr and abs internal for the sparc
|
* made sqrt, sqr and abs internal for the sparc
|
||||||
|
|
||||||
Revision 1.125 2004/09/25 14:23:55 peter
|
Revision 1.125 2004/09/25 14:23:55 peter
|
||||||
|
@ -36,10 +36,21 @@ unit rgx86;
|
|||||||
|
|
||||||
type
|
type
|
||||||
trgx86 = class(trgobj)
|
trgx86 = class(trgobj)
|
||||||
|
{$ifdef OLDRGX86}
|
||||||
function instr_spill_register(list:Taasmoutput;
|
function instr_spill_register(list:Taasmoutput;
|
||||||
instr:taicpu;
|
instr:taicpu;
|
||||||
const r:Tsuperregisterset;
|
const r:Tsuperregisterset;
|
||||||
const spilltemplist:Tspill_temp_list): boolean;override;
|
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;
|
||||||
|
}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
tpushedsavedloc = record
|
tpushedsavedloc = record
|
||||||
@ -107,6 +118,7 @@ implementation
|
|||||||
Trgcpu
|
Trgcpu
|
||||||
******************************************************************************}
|
******************************************************************************}
|
||||||
|
|
||||||
|
{$ifdef OLDRGX86}
|
||||||
function trgx86.instr_spill_register(list:Taasmoutput;
|
function trgx86.instr_spill_register(list:Taasmoutput;
|
||||||
instr:taicpu;
|
instr:taicpu;
|
||||||
const r:Tsuperregisterset;
|
const r:Tsuperregisterset;
|
||||||
@ -485,8 +497,67 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
{$endif OLDRGX86}
|
||||||
|
|
||||||
|
|
||||||
|
function trgx86.get_spill_subreg(r : tregister) : tsubregister;
|
||||||
|
begin
|
||||||
|
result:=getsubreg(r);
|
||||||
|
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;
|
||||||
|
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);
|
||||||
|
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
|
||||||
******************************************************************************}
|
******************************************************************************}
|
||||||
@ -619,7 +690,14 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.6 2004-09-27 14:49:45 peter
|
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.
|
||||||
|
* Spilling fixed when both operands needed to be spilled
|
||||||
|
* Cleanup of spilling routine, do_spill_readwritten removed
|
||||||
|
|
||||||
|
Revision 1.6 2004/09/27 14:49:45 peter
|
||||||
* handle 3 operand opcodes the same as 2 operand opcodes, the
|
* handle 3 operand opcodes the same as 2 operand opcodes, the
|
||||||
third operand can only be a const or register CL, so it doesn't
|
third operand can only be a const or register CL, so it doesn't
|
||||||
affect spilling
|
affect spilling
|
||||||
|
Loading…
Reference in New Issue
Block a user