* 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:
peter 2004-10-04 20:46:22 +00:00
parent ec720a5800
commit ee3585f56f
8 changed files with 349 additions and 352 deletions

View File

@ -140,7 +140,7 @@ begin
end
end;
else
for opCount := 1 to MaxCh do
for opCount := 1 to maxinschanges do
case InsProp[p.opcode].Ch[opCount] of
Ch_MOp1,CH_WOp1,CH_RWOp1:
if not(onlymem) or
@ -904,7 +904,7 @@ begin
begin
NoHardCodedRegs := true;
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
begin
NoHardCodedRegs := false;
@ -1058,7 +1058,7 @@ begin
{ updateStates(orgReg,newReg,p,false);}
doReplaceReadReg := true;
end;
for opCount := 1 to MaxCh do
for opCount := 1 to maxinschanges do
case InsProp[p.opcode].Ch[opCount] of
Ch_ROp1:
if p.oper[0]^.typ = top_reg then
@ -1901,7 +1901,7 @@ begin
ptaiprop(tai(p).optinfo)^.CanBeRemoved := True;
else
begin
for cnt := 1 to maxch do
for cnt := 1 to maxinschanges do
begin
case InsProp[taicpu(p).opcode].Ch[cnt] of
Ch_ROp1:
@ -2109,7 +2109,14 @@ end.
{
$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
Revision 1.64.4.1 2004/09/20 19:28:23 peter

View File

@ -725,7 +725,7 @@ begin
RegReadByInstruction := true;
exit
end;
for opcount := 1 to maxch do
for opcount := 1 to maxinschanges do
case insprop[p.opcode].ch[opcount] of
CH_REAX..CH_REDI,CH_RWEAX..CH_MEDI:
if supreg = tch2reg(insprop[p.opcode].ch[opcount]) then
@ -791,7 +791,7 @@ begin
(supreg in [RS_EAX,RS_EDX])
else
begin
for opcount := 1 to MaxCh do
for opcount := 1 to maxinschanges do
case insprop[p.opcode].Ch[opCount] of
CH_REAX..CH_MEDI:
if tch2reg(InsProp[p.opcode].Ch[opCount]) = supreg then
@ -866,7 +866,7 @@ begin
begin
Cnt := 1;
InstrProp := InsProp[taicpu(p1).OpCode];
while (Cnt <= MaxCh) and
while (Cnt <= maxinschanges) and
(InstrProp.Ch[Cnt] <> Ch_None) and
not(TmpResult) Do
begin
@ -901,7 +901,7 @@ begin
case p.typ of
ait_instruction:
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
exit;
end;
@ -920,7 +920,7 @@ begin
case p.typ of
ait_instruction:
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
exit;
end;
@ -2555,7 +2555,7 @@ begin
else
begin
Cnt := 1;
while (Cnt <= MaxCh) and
while (Cnt <= maxinschanges) and
(InstrProp.Ch[Cnt] <> Ch_None) Do
begin
case InstrProp.Ch[Cnt] Of
@ -2719,7 +2719,14 @@ end.
{
$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
Revision 1.68 2004/06/20 08:55:31 florian

View File

@ -28,49 +28,6 @@ unit optbase;
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
@ -79,7 +36,14 @@ end.
{
$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
}

View File

@ -135,8 +135,6 @@ unit rgobj;
trgobj=class
preserved_by_proc : tcpuregisterset;
used_in_proc : tcpuregisterset;
// is_reg_var : Tsuperregisterset; {old regvars}
// reg_var_loaded:Tsuperregisterset; {old regvars}
constructor create(Aregtype:Tregistertype;
Adefaultsub:Tsubregister;
@ -170,25 +168,12 @@ unit rgobj;
live_registers:Tsuperregisterworklist;
{ can be overriden to add cpu specific interferences }
procedure add_cpu_interferences(p : tai);virtual;
function get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister):Tai;
procedure forward_allocation(pfrom,pto:Tai);
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);
procedure add_constraints(reg:Tregister);virtual;
function get_spill_subreg(r : tregister) : tsubregister;virtual;
procedure do_spill_read(list:Taasmoutput;instr:Taicpu;
pos:Tai;regidx:word;
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;
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 instr_spill_register(list:Taasmoutput;
instr:taicpu;
@ -603,22 +588,12 @@ unit rgobj;
procedure trgobj.add_edges_used(u:Tsuperregister);
var i:word;
v:tsuperregister;
begin
with live_registers do
if length>0 then
for i:=0 to length-1 do
begin
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;
add_edge(u,get_alias(buf^[i]));
end;
{$ifdef EXTDEBUG}
@ -1638,69 +1613,6 @@ unit rgobj;
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;
{ Returns true if any help registers have been used }
var
@ -1790,65 +1702,22 @@ unit rgobj;
end;
procedure Trgobj.do_spill_read(list:Taasmoutput;instr:taicpu;
pos:Tai;regidx:word;
const spilltemplist:Tspill_temp_list;
const regs:Tspillregsinfo);
var helpins:Tai;
begin
with regs[regidx] do
begin
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;
procedure Trgobj.do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
var
helpins : Tai;
begin
helpins:=spilling_create_load(spilltemp,tempreg);
list.insertbefore(helpins,instr);
end;
procedure Trgobj.do_spill_written(list:Taasmoutput;instr:taicpu;
pos:Tai;regidx:word;
const spilltemplist:Tspill_temp_list;
const regs:Tspillregsinfo);
var helpins:Tai;
begin
with regs[regidx] do
begin
helpins:=spilling_create_store(tempreg,spilltemplist[orgreg]);
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;
procedure Trgobj.do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
var
helpins : Tai;
begin
helpins:=spilling_create_store(tempreg,spilltemp);
list.insertafter(helpins,instr);
end;
function trgobj.get_spill_subreg(r : tregister) : tsubregister;
@ -1863,7 +1732,6 @@ unit rgobj;
const spilltemplist:Tspill_temp_list): boolean;
var
counter, regindex: longint;
pos: tai;
regs: tspillregsinfo;
spilled: boolean;
@ -1874,7 +1742,7 @@ unit rgobj;
begin
tmpindex := regindex;
supreg:=getsupreg(reg);
// did we already encounter this register?
{ did we already encounter this register? }
for i := 0 to pred(regindex) do
if (regs[i].orgreg = supreg) then
begin
@ -1887,7 +1755,7 @@ unit rgobj;
regs[tmpindex].spillreg:=reg;
if supregset_in(r,supreg) then
begin
// add/update info on this register
{ add/update info on this register }
regs[tmpindex].mustbespilled := true;
case operation of
operand_read:
@ -1916,12 +1784,15 @@ unit rgobj;
if (regs[i].mustbespilled) and
(regs[i].orgreg=supreg) then
begin
reg:=regs[i].tempreg;
{ Only replace supreg }
setsupreg(reg,getsupreg(regs[i].tempreg));
break;
end;
end;
var
counter2 : longint;
oldlive_registers : tsuperregisterworklist;
begin
result := false;
fillchar(regs,sizeof(regs),0);
@ -1966,6 +1837,14 @@ 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;
for counter := 0 to pred(regindex) do
@ -1973,18 +1852,27 @@ unit rgobj;
begin
if mustbespilled then
begin
pos:=get_insert_pos(Tai(instr.previous),regs[0].orgreg,regs[1].orgreg,regs[2].orgreg);
getregisterinline(list,pos,get_spill_subreg(regs[counter].spillreg),tempreg);
getregisterinline(list,tai(instr.previous),get_spill_subreg(regs[counter].spillreg),tempreg);
if regread then
if regwritten then
do_spill_readwritten(list,instr,pos,counter,spilltemplist,regs)
else
do_spill_read(list,instr,pos,counter,spilltemplist,regs)
else
do_spill_written(list,instr,pos,counter,spilltemplist,regs)
do_spill_read(list,instr,spilltemplist[orgreg],tempreg);
if regwritten then
do_spill_written(list,instr,spilltemplist[orgreg],tempreg);
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 }
for counter:=0 to instr.ops-1 do
with instr.oper[counter]^ do
@ -2015,7 +1903,14 @@ unit rgobj;
end.
{
$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
Revision 1.136 2004/09/25 14:23:54 peter

View File

@ -36,12 +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;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;
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;
end;
@ -91,159 +87,89 @@ implementation
end;
procedure trgcpu.do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
procedure trgcpu.do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
var
helpins: tai;
tmpref,ref : treference;
helpins : tai;
tmpref : treference;
helplist : taasmoutput;
tmpreg : tregister;
hreg : tregister;
begin
ref:=spilltemplist[regs[regidx].orgreg];
if abs(ref.offset)>4095 then
if abs(spilltemp.offset)>4095 then
begin
helplist:=taasmoutput.create;
reference_reset(tmpref);
if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
getregisterinline(helplist,nil,defaultsub,tmpreg)
if getregtype(tempreg)=R_INTREGISTER then
hreg:=tempreg
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;
helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,tmpreg));
helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,hreg));
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
internalerror(200401263);
ref.index:=tmpreg;
ref.offset:=0;
reference_reset_base(tmpref,hreg,0);
helpins:=spilling_create_load(ref,regs[regidx].tempreg);
helpins:=spilling_create_load(spilltemp,tempreg);
helplist.concat(helpins);
if pos=nil then
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);
list.insertlistbefore(instr,helplist)
end
else
inherited do_spill_read(list,instr,pos,regidx,spilltemplist,regs);
inherited do_spill_read(list,instr,spilltemp,tempreg);
end;
procedure trgcpu.do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
procedure trgcpu.do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
var
helpins: tai;
ref,tmpref : treference;
helpins : tai;
tmpref : treference;
helplist : taasmoutput;
tmpreg : tregister;
hreg : tregister;
begin
ref:=spilltemplist[regs[regidx].orgreg];
if abs(ref.offset)>4095 then
if abs(spilltemp.offset)>4095 then
begin
helplist:=taasmoutput.create;
reference_reset(tmpref);
if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
getregisterinline(helplist,pos,defaultsub,tmpreg)
if getregtype(tempreg)=R_INTREGISTER then
getregisterinline(helplist,tai(helplist.first),R_SUBWHOLE,hreg)
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;
helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,tmpreg));
helplist.concat(taicpu.op_ref_reg(A_SETHI,tmpref,hreg));
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
internalerror(200401263);
ref.index:=tmpreg;
ref.offset:=0;
reference_reset_base(tmpref,hreg,0);
helpins:=spilling_create_store(regs[regidx].tempreg,ref);
helpins:=spilling_create_store(tempreg,spilltemp);
helplist.concat(helpins);
list.insertlistafter(instr,helplist);
helplist.free;
if getregtype(tempreg)=R_INTREGISTER then
ungetregisterinline(helplist,tai(helplist.last),hreg);
ungetregisterinline(list,helpins,regs[regidx].tempreg);
if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
ungetregisterinline(list,helpins,tmpreg);
list.insertlistafter(instr,helplist)
end
else
inherited do_spill_written(list,instr,pos,regidx,spilltemplist,regs);
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;
inherited do_spill_written(list,instr,spilltemp,tempreg);
end;
end.
{
$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
Revision 1.26 2004/09/28 20:19:36 peter

View File

@ -130,6 +130,36 @@ interface
instabentries = {$i i386nop.inc}
{$endif x86_64}
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
TOperandOrder = (op_intel,op_att);
@ -201,6 +231,8 @@ interface
procedure Pass2(objdata:TAsmObjectdata);virtual;
procedure SetOperandOrder(order:TOperandOrder);
function is_same_reg_move(regtype: Tregistertype):boolean;override;
{ register spilling code }
function spilling_get_operation_type(opnr: longint): topertype;override;
protected
procedure ppuloadoper(ppufile:tcompilerppufile;var o:toper);override;
procedure ppuwriteoper(ppufile:tcompilerppufile;const o:toper);override;
@ -366,6 +398,12 @@ implementation
);
{$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
@ -1932,15 +1970,74 @@ implementation
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;
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;
function spilling_create_store(r:tregister; const ref:treference): tai;
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;
@ -1970,6 +2067,7 @@ implementation
procedure InitAsm;
begin
build_spilling_operation_type_table;
{$ifndef NOAG386BIN}
if not assigned(instabcache) then
BuildInsTabCache;
@ -1979,12 +2077,17 @@ implementation
procedure DoneAsm;
begin
if assigned(operation_type_table) then
begin
dispose(operation_type_table);
operation_type_table:=nil;
end;
{$ifndef NOAG386BIN}
if assigned(instabcache) then
begin
dispose(instabcache);
instabcache:=nil;
end;
begin
dispose(instabcache);
instabcache:=nil;
end;
{$endif NOAG386BIN}
end;
@ -1995,7 +2098,14 @@ begin
end.
{
$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
Revision 1.57 2004/06/20 08:55:32 florian

View File

@ -551,11 +551,14 @@ unit cgx86;
if s in [S_BL,S_WL,S_L] then
reg2:=makeregsize(list,reg2,OS_32);
{$endif x86_64}
instr:=taicpu.op_reg_reg(op,s,reg1,reg2);
{ Notify the register allocator that we have written a move instruction so
it can try to eliminate it. }
add_move_instruction(instr);
list.concat(instr);
if (reg1<>reg2) then
begin
instr:=taicpu.op_reg_reg(op,s,reg1,reg2);
{ Notify the register allocator that we have written a move instruction so
it can try to eliminate it. }
add_move_instruction(instr);
list.concat(instr);
end;
end;
@ -1672,7 +1675,14 @@ unit cgx86;
end.
{
$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
Revision 1.125 2004/09/25 14:23:55 peter

View File

@ -36,10 +36,21 @@ 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;
}
end;
tpushedsavedloc = record
@ -107,6 +118,7 @@ implementation
Trgcpu
******************************************************************************}
{$ifdef OLDRGX86}
function trgx86.instr_spill_register(list:Taasmoutput;
instr:taicpu;
const r:Tsuperregisterset;
@ -485,8 +497,67 @@ implementation
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
******************************************************************************}
@ -619,7 +690,14 @@ implementation
end.
{
$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
third operand can only be a const or register CL, so it doesn't
affect spilling