mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 23:59:10 +02:00
* reg allocations for imaginary register are now inserted just
before reg allocation * tregister changed to enum to allow compile time check * fixed several tregister-tsuperregister errors
This commit is contained in:
parent
e60da116b0
commit
1367e342db
@ -447,6 +447,7 @@ interface
|
|||||||
|
|
||||||
Taasmoutput=class;
|
Taasmoutput=class;
|
||||||
|
|
||||||
|
tadd_reg_instruction_proc=procedure(instr:Tai;r:tregister) of object;
|
||||||
Trggetproc=procedure(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister) of object;
|
Trggetproc=procedure(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister) of object;
|
||||||
Trgungetproc=procedure(list:Taasmoutput;position:Tai;r:Tregister) of object;
|
Trgungetproc=procedure(list:Taasmoutput;position:Tai;r:Tregister) of object;
|
||||||
|
|
||||||
@ -491,7 +492,7 @@ interface
|
|||||||
procedure loadoper(opidx:longint;o:toper);
|
procedure loadoper(opidx:longint;o:toper);
|
||||||
procedure clearop(opidx:longint);
|
procedure clearop(opidx:longint);
|
||||||
function is_nop:boolean;virtual;abstract;
|
function is_nop:boolean;virtual;abstract;
|
||||||
function is_move:boolean;virtual;abstract;
|
function is_reg_move:boolean;virtual;abstract;
|
||||||
{ register allocator }
|
{ register allocator }
|
||||||
function get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister;var live_registers_int:Tsuperregisterworklist):Tai;
|
function get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister;var live_registers_int:Tsuperregisterworklist):Tai;
|
||||||
procedure forward_allocation(p:Tai;var {unusedregsint:tsuperregisterset}live_registers_int:Tsuperregisterworklist);
|
procedure forward_allocation(p:Tai;var {unusedregsint:tsuperregisterset}live_registers_int:Tsuperregisterworklist);
|
||||||
@ -542,6 +543,9 @@ interface
|
|||||||
{ label when the result is true or false }
|
{ label when the result is true or false }
|
||||||
truelabel,falselabel : tasmlabel;
|
truelabel,falselabel : tasmlabel;
|
||||||
|
|
||||||
|
{ hook to notify uses of registers }
|
||||||
|
add_reg_instruction_hook : tadd_reg_instruction_proc;
|
||||||
|
|
||||||
{ default lists }
|
{ default lists }
|
||||||
datasegment,codesegment,bsssegment,
|
datasegment,codesegment,bsssegment,
|
||||||
debuglist,withdebuglist,consts,
|
debuglist,withdebuglist,consts,
|
||||||
@ -1677,6 +1681,8 @@ implementation
|
|||||||
segprefix:=ref^.segment;
|
segprefix:=ref^.segment;
|
||||||
{$endif}
|
{$endif}
|
||||||
typ:=top_ref;
|
typ:=top_ref;
|
||||||
|
add_reg_instruction_hook(self,ref^.base);
|
||||||
|
add_reg_instruction_hook(self,ref^.index);
|
||||||
{ mark symbol as used }
|
{ mark symbol as used }
|
||||||
if assigned(ref^.symbol) then
|
if assigned(ref^.symbol) then
|
||||||
ref^.symbol.increfs;
|
ref^.symbol.increfs;
|
||||||
@ -1694,6 +1700,7 @@ implementation
|
|||||||
reg:=r;
|
reg:=r;
|
||||||
typ:=top_reg;
|
typ:=top_reg;
|
||||||
end;
|
end;
|
||||||
|
add_reg_instruction_hook(self,r);
|
||||||
{$ifdef ARM}
|
{$ifdef ARM}
|
||||||
{ R15 is the PC on the ARM thus moves to R15 are jumps.
|
{ R15 is the PC on the ARM thus moves to R15 are jumps.
|
||||||
Due to speed considerations we don't use a virtual overridden method here.
|
Due to speed considerations we don't use a virtual overridden method here.
|
||||||
@ -1714,10 +1721,14 @@ implementation
|
|||||||
with oper[opidx]^ do
|
with oper[opidx]^ do
|
||||||
begin
|
begin
|
||||||
case typ of
|
case typ of
|
||||||
|
top_reg:
|
||||||
|
add_reg_instruction_hook(self,reg);
|
||||||
top_ref:
|
top_ref:
|
||||||
begin
|
begin
|
||||||
new(ref);
|
new(ref);
|
||||||
ref^:=o.ref^;
|
ref^:=o.ref^;
|
||||||
|
add_reg_instruction_hook(self,ref^.base);
|
||||||
|
add_reg_instruction_hook(self,ref^.index);
|
||||||
end;
|
end;
|
||||||
{$ifdef ARM}
|
{$ifdef ARM}
|
||||||
top_shifterop:
|
top_shifterop:
|
||||||
@ -2202,7 +2213,13 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.60 2003-12-14 20:24:28 daniel
|
Revision 1.61 2003-12-15 21:25:48 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.60 2003/12/14 20:24:28 daniel
|
||||||
* Register allocator speed optimizations
|
* Register allocator speed optimizations
|
||||||
- Worklist no longer a ringbuffer
|
- Worklist no longer a ringbuffer
|
||||||
- No find operations are left
|
- No find operations are left
|
||||||
|
@ -133,12 +133,17 @@ interface
|
|||||||
{
|
{
|
||||||
The new register coding:
|
The new register coding:
|
||||||
|
|
||||||
SuperRegister (bits 0..7)
|
SuperRegister (bits 0..15)
|
||||||
Unused (bits 8..15)
|
|
||||||
Subregister (bits 16..23)
|
Subregister (bits 16..23)
|
||||||
Register type (bits 24..31)
|
Register type (bits 24..31)
|
||||||
|
|
||||||
|
TRegister is defined as an enum to make it incompatible
|
||||||
|
with TSuperRegister to avoid mixing them
|
||||||
}
|
}
|
||||||
TRegister = type cardinal;
|
TRegister = (
|
||||||
|
TRegisterLowEnum := $80000000,
|
||||||
|
TRegisterHighEnum := $7fffffff
|
||||||
|
);
|
||||||
TRegisterRec=packed record
|
TRegisterRec=packed record
|
||||||
{$ifdef FPC_BIG_ENDIAN}
|
{$ifdef FPC_BIG_ENDIAN}
|
||||||
regtype : Tregistertype;
|
regtype : Tregistertype;
|
||||||
@ -316,7 +321,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
destructor tsuperregisterworklist.done;
|
destructor tsuperregisterworklist.done;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if assigned(buf) then
|
if assigned(buf) then
|
||||||
freemem(buf);
|
freemem(buf);
|
||||||
@ -324,7 +329,7 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
procedure tsuperregisterworklist.add(s:tsuperregister);
|
procedure tsuperregisterworklist.add(s:tsuperregister);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
inc(length);
|
inc(length);
|
||||||
{ Need to increase buffer length? }
|
{ Need to increase buffer length? }
|
||||||
@ -341,14 +346,14 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
procedure tsuperregisterworklist.clear;
|
procedure tsuperregisterworklist.clear;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
length:=0;
|
length:=0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tsuperregisterworklist.deleteidx(i:word);
|
procedure tsuperregisterworklist.deleteidx(i:word);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if length=0 then
|
if length=0 then
|
||||||
internalerror(200310144);
|
internalerror(200310144);
|
||||||
@ -358,7 +363,7 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
function tsuperregisterworklist.get:tsuperregister;
|
function tsuperregisterworklist.get:tsuperregister;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if length=0 then
|
if length=0 then
|
||||||
internalerror(200310142);
|
internalerror(200310142);
|
||||||
@ -369,9 +374,9 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
function tsuperregisterworklist.delete(s:tsuperregister):boolean;
|
function tsuperregisterworklist.delete(s:tsuperregister):boolean;
|
||||||
|
|
||||||
var i:word;
|
var i:word;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
delete:=false;
|
delete:=false;
|
||||||
for i:=1 to length do
|
for i:=1 to length do
|
||||||
@ -569,7 +574,13 @@ finalization
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.78 2003-12-14 20:24:28 daniel
|
Revision 1.79 2003-12-15 21:25:48 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.78 2003/12/14 20:24:28 daniel
|
||||||
* Register allocator speed optimizations
|
* Register allocator speed optimizations
|
||||||
- Worklist no longer a ringbuffer
|
- Worklist no longer a ringbuffer
|
||||||
- No find operations are left
|
- No find operations are left
|
||||||
|
@ -84,6 +84,7 @@ unit cgobj;
|
|||||||
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;
|
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;
|
||||||
procedure ungetreference(list:Taasmoutput;const r:Treference);virtual;
|
procedure ungetreference(list:Taasmoutput;const r:Treference);virtual;
|
||||||
|
|
||||||
|
procedure add_reg_instruction(instr:Tai;r:tregister);virtual;
|
||||||
procedure add_move_instruction(instr:Taicpu);virtual;
|
procedure add_move_instruction(instr:Taicpu);virtual;
|
||||||
|
|
||||||
function uses_registers(rt:Tregistertype):boolean;virtual;
|
function uses_registers(rt:Tregistertype):boolean;virtual;
|
||||||
@ -553,6 +554,7 @@ implementation
|
|||||||
|
|
||||||
constructor tcg.create;
|
constructor tcg.create;
|
||||||
begin
|
begin
|
||||||
|
add_reg_instruction_hook:={$ifdef FPCPROCVAR}@{$endif}add_reg_instruction;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -627,6 +629,8 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if r.base<>NR_NO then
|
if r.base<>NR_NO then
|
||||||
ungetregister(list,r.base);
|
ungetregister(list,r.base);
|
||||||
|
if r.index<>NR_NO then
|
||||||
|
ungetregister(list,r.index);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -657,6 +661,19 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg.add_reg_instruction(instr:Tai;r:tregister);
|
||||||
|
var
|
||||||
|
rt : tregistertype;
|
||||||
|
begin
|
||||||
|
rt:=getregtype(r);
|
||||||
|
{ Only add it when a register allocator is configured.
|
||||||
|
No IE can be generated, because the VMT is written
|
||||||
|
without a valid rg[] }
|
||||||
|
if assigned(rg[rt]) then
|
||||||
|
rg[rt].add_reg_instruction(instr,r);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcg.add_move_instruction(instr:Taicpu);
|
procedure tcg.add_move_instruction(instr:Taicpu);
|
||||||
var
|
var
|
||||||
rt : tregistertype;
|
rt : tregistertype;
|
||||||
@ -676,11 +693,7 @@ implementation
|
|||||||
for rt:=low(tregistertype) to high(tregistertype) do
|
for rt:=low(tregistertype) to high(tregistertype) do
|
||||||
begin
|
begin
|
||||||
if assigned(rg[rt]) then
|
if assigned(rg[rt]) then
|
||||||
begin
|
rg[rt].do_register_allocation(list,headertai);
|
||||||
rg[rt].check_unreleasedregs;
|
|
||||||
rg[rt].do_register_allocation(list,headertai);
|
|
||||||
rg[rt].translate_registers(list);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1941,7 +1954,13 @@ finalization
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.138 2003-12-12 17:16:17 peter
|
Revision 1.139 2003-12-15 21:25:48 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.138 2003/12/12 17:16:17 peter
|
||||||
* rg[tregistertype] added in tcg
|
* rg[tregistertype] added in tcg
|
||||||
|
|
||||||
Revision 1.137 2003/12/06 22:11:47 jonas
|
Revision 1.137 2003/12/06 22:11:47 jonas
|
||||||
|
@ -178,7 +178,7 @@ begin
|
|||||||
tmpRef.base := NR_EDI;
|
tmpRef.base := NR_EDI;
|
||||||
tmpRef.index := NR_EDI;
|
tmpRef.index := NR_EDI;
|
||||||
for regCounter := RS_EAX to RS_EDI do
|
for regCounter := RS_EAX to RS_EDI do
|
||||||
if writeToMemDestroysContents(NR_NO,tmpRef,regCounter,c[regCounter],dummy) then
|
if writeToMemDestroysContents(RS_INVALID,tmpRef,regCounter,c[regCounter],dummy) then
|
||||||
begin
|
begin
|
||||||
exclude(regsStillValid,regCounter);
|
exclude(regsStillValid,regCounter);
|
||||||
modifiesConflictingMemLocation := not(supreg in regsStillValid);
|
modifiesConflictingMemLocation := not(supreg in regsStillValid);
|
||||||
@ -1954,7 +1954,7 @@ begin
|
|||||||
if (memreg <> NR_NO) and
|
if (memreg <> NR_NO) and
|
||||||
(not getNextInstruction(p,hp1) or
|
(not getNextInstruction(p,hp1) or
|
||||||
(RegLoadedWithNewValue(getsupreg(memreg),false,hp1) or
|
(RegLoadedWithNewValue(getsupreg(memreg),false,hp1) or
|
||||||
FindRegDealloc(getsupreg(regcounter),hp1))) then
|
FindRegDealloc(regcounter,hp1))) then
|
||||||
begin
|
begin
|
||||||
hp1 := Tai_Marker.Create(NoPropInfoEnd);
|
hp1 := Tai_Marker.Create(NoPropInfoEnd);
|
||||||
insertllitem(asml,p,p.next,hp1);
|
insertllitem(asml,p,p.next,hp1);
|
||||||
@ -2074,7 +2074,13 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.57 2003-12-15 16:08:15 jonas
|
Revision 1.58 2003-12-15 21:25:49 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.57 2003/12/15 16:08:15 jonas
|
||||||
- disable removal of dead loads before a call, because register
|
- disable removal of dead loads before a call, because register
|
||||||
parameters are released before a call
|
parameters are released before a call
|
||||||
* fix storeback of registers in case of different sizes (e.g., first
|
* fix storeback of registers in case of different sizes (e.g., first
|
||||||
|
@ -1785,7 +1785,7 @@ begin
|
|||||||
(typ in [con_ref,con_noRemoveRef]) and
|
(typ in [con_ref,con_noRemoveRef]) and
|
||||||
(not(cs_UncertainOpts in aktglobalswitches) or
|
(not(cs_UncertainOpts in aktglobalswitches) or
|
||||||
{ for movsl }
|
{ for movsl }
|
||||||
((ref.base = RS_EDI) and (ref.index = RS_EDI)) or
|
((ref.base = NR_EDI) and (ref.index = NR_EDI)) or
|
||||||
{ don't destroy if reg contains a parameter, local or global variable }
|
{ don't destroy if reg contains a parameter, local or global variable }
|
||||||
containsPointerLoad(c)
|
containsPointerLoad(c)
|
||||||
);
|
);
|
||||||
@ -1963,7 +1963,7 @@ var
|
|||||||
p, prev: tai;
|
p, prev: tai;
|
||||||
hp1, hp2: tai;
|
hp1, hp2: tai;
|
||||||
{$ifdef i386}
|
{$ifdef i386}
|
||||||
regcounter: tregister;
|
regcounter,
|
||||||
supreg : tsuperregister;
|
supreg : tsuperregister;
|
||||||
{$endif i386}
|
{$endif i386}
|
||||||
usedregs, nodeallocregs: tregset;
|
usedregs, nodeallocregs: tregset;
|
||||||
@ -2052,7 +2052,7 @@ begin
|
|||||||
usedRegs := usedRegs - noDeallocRegs;
|
usedRegs := usedRegs - noDeallocRegs;
|
||||||
for regCounter := RS_EAX to RS_EDI do
|
for regCounter := RS_EAX to RS_EDI do
|
||||||
if regCounter in usedRegs then
|
if regCounter in usedRegs then
|
||||||
addRegDeallocFor(list,regCounter,prev);
|
addRegDeallocFor(list,newreg(R_INTREGISTER,regCounter,R_SUBWHOLE),prev);
|
||||||
{$endif i386}
|
{$endif i386}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2714,7 +2714,13 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.60 2003-12-15 15:58:58 peter
|
Revision 1.61 2003-12-15 21:25:49 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.60 2003/12/15 15:58:58 peter
|
||||||
* fix statedebug compile
|
* fix statedebug compile
|
||||||
|
|
||||||
Revision 1.59 2003/12/14 22:42:14 peter
|
Revision 1.59 2003/12/14 22:42:14 peter
|
||||||
|
@ -1808,7 +1808,7 @@ begin
|
|||||||
TmpUsedRegs := UsedRegs;
|
TmpUsedRegs := UsedRegs;
|
||||||
UpdateUsedRegs(TmpUsedRegs,tai(hp1.next));
|
UpdateUsedRegs(TmpUsedRegs,tai(hp1.next));
|
||||||
if (RefsEqual(taicpu(hp2).oper[1]^.ref^, taicpu(p).oper[0]^.ref^) and
|
if (RefsEqual(taicpu(hp2).oper[1]^.ref^, taicpu(p).oper[0]^.ref^) and
|
||||||
not(RegUsedAfterInstruction(getsupreg(taicpu(p).oper[1]^.reg),
|
not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,
|
||||||
hp2, TmpUsedRegs))) then
|
hp2, TmpUsedRegs))) then
|
||||||
{ change mov (ref), reg }
|
{ change mov (ref), reg }
|
||||||
{ add/sub/or/... reg2/$const, reg }
|
{ add/sub/or/... reg2/$const, reg }
|
||||||
@ -1996,7 +1996,13 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.52 2003-12-14 22:42:14 peter
|
Revision 1.53 2003-12-15 21:25:49 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.52 2003/12/14 22:42:14 peter
|
||||||
* fixed csdebug
|
* fixed csdebug
|
||||||
|
|
||||||
Revision 1.51 2003/12/13 15:48:47 jonas
|
Revision 1.51 2003/12/13 15:48:47 jonas
|
||||||
|
@ -1,72 +1,72 @@
|
|||||||
{ don't edit, this file is generated from x86reg.dat }
|
{ don't edit, this file is generated from x86reg.dat }
|
||||||
NR_NO = $00000000;
|
NR_NO = tregister($00000000);
|
||||||
NR_AL = $01010000;
|
NR_AL = tregister($01010000);
|
||||||
NR_AH = $01020000;
|
NR_AH = tregister($01020000);
|
||||||
NR_AX = $01030000;
|
NR_AX = tregister($01030000);
|
||||||
NR_EAX = $01040000;
|
NR_EAX = tregister($01040000);
|
||||||
NR_CL = $01010001;
|
NR_CL = tregister($01010001);
|
||||||
NR_CH = $01020001;
|
NR_CH = tregister($01020001);
|
||||||
NR_CX = $01030001;
|
NR_CX = tregister($01030001);
|
||||||
NR_ECX = $01040001;
|
NR_ECX = tregister($01040001);
|
||||||
NR_DL = $01010002;
|
NR_DL = tregister($01010002);
|
||||||
NR_DH = $01020002;
|
NR_DH = tregister($01020002);
|
||||||
NR_DX = $01030002;
|
NR_DX = tregister($01030002);
|
||||||
NR_EDX = $01040002;
|
NR_EDX = tregister($01040002);
|
||||||
NR_BL = $01010003;
|
NR_BL = tregister($01010003);
|
||||||
NR_BH = $01020003;
|
NR_BH = tregister($01020003);
|
||||||
NR_BX = $01030003;
|
NR_BX = tregister($01030003);
|
||||||
NR_EBX = $01040003;
|
NR_EBX = tregister($01040003);
|
||||||
NR_SI = $01030004;
|
NR_SI = tregister($01030004);
|
||||||
NR_ESI = $01040004;
|
NR_ESI = tregister($01040004);
|
||||||
NR_DI = $01030005;
|
NR_DI = tregister($01030005);
|
||||||
NR_EDI = $01040005;
|
NR_EDI = tregister($01040005);
|
||||||
NR_BP = $01030006;
|
NR_BP = tregister($01030006);
|
||||||
NR_EBP = $01040006;
|
NR_EBP = tregister($01040006);
|
||||||
NR_SP = $01030007;
|
NR_SP = tregister($01030007);
|
||||||
NR_ESP = $01040007;
|
NR_ESP = tregister($01040007);
|
||||||
NR_CS = $05000001;
|
NR_CS = tregister($05000001);
|
||||||
NR_DS = $05000002;
|
NR_DS = tregister($05000002);
|
||||||
NR_ES = $05000003;
|
NR_ES = tregister($05000003);
|
||||||
NR_SS = $05000004;
|
NR_SS = tregister($05000004);
|
||||||
NR_FS = $05000005;
|
NR_FS = tregister($05000005);
|
||||||
NR_GS = $05000006;
|
NR_GS = tregister($05000006);
|
||||||
NR_DR0 = $05000007;
|
NR_DR0 = tregister($05000007);
|
||||||
NR_DR1 = $05000008;
|
NR_DR1 = tregister($05000008);
|
||||||
NR_DR2 = $05000009;
|
NR_DR2 = tregister($05000009);
|
||||||
NR_DR3 = $0500000a;
|
NR_DR3 = tregister($0500000a);
|
||||||
NR_DR6 = $0500000b;
|
NR_DR6 = tregister($0500000b);
|
||||||
NR_DR7 = $0500000c;
|
NR_DR7 = tregister($0500000c);
|
||||||
NR_CR0 = $0500000d;
|
NR_CR0 = tregister($0500000d);
|
||||||
NR_CR2 = $0500000e;
|
NR_CR2 = tregister($0500000e);
|
||||||
NR_CR3 = $0500000f;
|
NR_CR3 = tregister($0500000f);
|
||||||
NR_CR4 = $05000010;
|
NR_CR4 = tregister($05000010);
|
||||||
NR_TR3 = $05000011;
|
NR_TR3 = tregister($05000011);
|
||||||
NR_TR4 = $05000012;
|
NR_TR4 = tregister($05000012);
|
||||||
NR_TR5 = $05000013;
|
NR_TR5 = tregister($05000013);
|
||||||
NR_TR6 = $05000014;
|
NR_TR6 = tregister($05000014);
|
||||||
NR_TR7 = $05000015;
|
NR_TR7 = tregister($05000015);
|
||||||
NR_ST0 = $02000000;
|
NR_ST0 = tregister($02000000);
|
||||||
NR_ST1 = $02000001;
|
NR_ST1 = tregister($02000001);
|
||||||
NR_ST2 = $02000002;
|
NR_ST2 = tregister($02000002);
|
||||||
NR_ST3 = $02000003;
|
NR_ST3 = tregister($02000003);
|
||||||
NR_ST4 = $02000004;
|
NR_ST4 = tregister($02000004);
|
||||||
NR_ST5 = $02000005;
|
NR_ST5 = tregister($02000005);
|
||||||
NR_ST6 = $02000006;
|
NR_ST6 = tregister($02000006);
|
||||||
NR_ST7 = $02000007;
|
NR_ST7 = tregister($02000007);
|
||||||
NR_ST = $02000008;
|
NR_ST = tregister($02000008);
|
||||||
NR_MM0 = $03000000;
|
NR_MM0 = tregister($03000000);
|
||||||
NR_MM1 = $03000001;
|
NR_MM1 = tregister($03000001);
|
||||||
NR_MM2 = $03000002;
|
NR_MM2 = tregister($03000002);
|
||||||
NR_MM3 = $03000003;
|
NR_MM3 = tregister($03000003);
|
||||||
NR_MM4 = $03000004;
|
NR_MM4 = tregister($03000004);
|
||||||
NR_MM5 = $03000005;
|
NR_MM5 = tregister($03000005);
|
||||||
NR_MM6 = $03000006;
|
NR_MM6 = tregister($03000006);
|
||||||
NR_MM7 = $03000007;
|
NR_MM7 = tregister($03000007);
|
||||||
NR_XMM0 = $04000000;
|
NR_XMM0 = tregister($04000000);
|
||||||
NR_XMM1 = $04000001;
|
NR_XMM1 = tregister($04000001);
|
||||||
NR_XMM2 = $04000002;
|
NR_XMM2 = tregister($04000002);
|
||||||
NR_XMM3 = $04000003;
|
NR_XMM3 = tregister($04000003);
|
||||||
NR_XMM4 = $04000004;
|
NR_XMM4 = tregister($04000004);
|
||||||
NR_XMM5 = $04000005;
|
NR_XMM5 = tregister($04000005);
|
||||||
NR_XMM6 = $04000006;
|
NR_XMM6 = tregister($04000006);
|
||||||
NR_XMM7 = $04000007;
|
NR_XMM7 = tregister($04000007);
|
||||||
|
@ -1,72 +1,72 @@
|
|||||||
{ don't edit, this file is generated from x86reg.dat }
|
{ don't edit, this file is generated from x86reg.dat }
|
||||||
$00000000,
|
tregister($00000000),
|
||||||
$01010000,
|
tregister($01010000),
|
||||||
$01020000,
|
tregister($01020000),
|
||||||
$01030000,
|
tregister($01030000),
|
||||||
$01040000,
|
tregister($01040000),
|
||||||
$01010001,
|
tregister($01010001),
|
||||||
$01020001,
|
tregister($01020001),
|
||||||
$01030001,
|
tregister($01030001),
|
||||||
$01040001,
|
tregister($01040001),
|
||||||
$01010002,
|
tregister($01010002),
|
||||||
$01020002,
|
tregister($01020002),
|
||||||
$01030002,
|
tregister($01030002),
|
||||||
$01040002,
|
tregister($01040002),
|
||||||
$01010003,
|
tregister($01010003),
|
||||||
$01020003,
|
tregister($01020003),
|
||||||
$01030003,
|
tregister($01030003),
|
||||||
$01040003,
|
tregister($01040003),
|
||||||
$01030004,
|
tregister($01030004),
|
||||||
$01040004,
|
tregister($01040004),
|
||||||
$01030005,
|
tregister($01030005),
|
||||||
$01040005,
|
tregister($01040005),
|
||||||
$01030006,
|
tregister($01030006),
|
||||||
$01040006,
|
tregister($01040006),
|
||||||
$01030007,
|
tregister($01030007),
|
||||||
$01040007,
|
tregister($01040007),
|
||||||
$05000001,
|
tregister($05000001),
|
||||||
$05000002,
|
tregister($05000002),
|
||||||
$05000003,
|
tregister($05000003),
|
||||||
$05000004,
|
tregister($05000004),
|
||||||
$05000005,
|
tregister($05000005),
|
||||||
$05000006,
|
tregister($05000006),
|
||||||
$05000007,
|
tregister($05000007),
|
||||||
$05000008,
|
tregister($05000008),
|
||||||
$05000009,
|
tregister($05000009),
|
||||||
$0500000a,
|
tregister($0500000a),
|
||||||
$0500000b,
|
tregister($0500000b),
|
||||||
$0500000c,
|
tregister($0500000c),
|
||||||
$0500000d,
|
tregister($0500000d),
|
||||||
$0500000e,
|
tregister($0500000e),
|
||||||
$0500000f,
|
tregister($0500000f),
|
||||||
$05000010,
|
tregister($05000010),
|
||||||
$05000011,
|
tregister($05000011),
|
||||||
$05000012,
|
tregister($05000012),
|
||||||
$05000013,
|
tregister($05000013),
|
||||||
$05000014,
|
tregister($05000014),
|
||||||
$05000015,
|
tregister($05000015),
|
||||||
$02000000,
|
tregister($02000000),
|
||||||
$02000001,
|
tregister($02000001),
|
||||||
$02000002,
|
tregister($02000002),
|
||||||
$02000003,
|
tregister($02000003),
|
||||||
$02000004,
|
tregister($02000004),
|
||||||
$02000005,
|
tregister($02000005),
|
||||||
$02000006,
|
tregister($02000006),
|
||||||
$02000007,
|
tregister($02000007),
|
||||||
$02000008,
|
tregister($02000008),
|
||||||
$03000000,
|
tregister($03000000),
|
||||||
$03000001,
|
tregister($03000001),
|
||||||
$03000002,
|
tregister($03000002),
|
||||||
$03000003,
|
tregister($03000003),
|
||||||
$03000004,
|
tregister($03000004),
|
||||||
$03000005,
|
tregister($03000005),
|
||||||
$03000006,
|
tregister($03000006),
|
||||||
$03000007,
|
tregister($03000007),
|
||||||
$04000000,
|
tregister($04000000),
|
||||||
$04000001,
|
tregister($04000001),
|
||||||
$04000002,
|
tregister($04000002),
|
||||||
$04000003,
|
tregister($04000003),
|
||||||
$04000004,
|
tregister($04000004),
|
||||||
$04000005,
|
tregister($04000005),
|
||||||
$04000006,
|
tregister($04000006),
|
||||||
$04000007
|
tregister($04000007)
|
||||||
|
@ -113,7 +113,7 @@ implementation
|
|||||||
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
||||||
internalerror(200304235);
|
internalerror(200304235);
|
||||||
location_release(exprasmlist,left.location);
|
location_release(exprasmlist,left.location);
|
||||||
allocate_tempparaloc;
|
// allocate_tempparaloc;
|
||||||
cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
|
cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
|
||||||
inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
|
inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
|
||||||
end;
|
end;
|
||||||
@ -137,7 +137,7 @@ implementation
|
|||||||
if left.resulttype.def.deftype=floatdef then
|
if left.resulttype.def.deftype=floatdef then
|
||||||
begin
|
begin
|
||||||
location_release(exprasmlist,left.location);
|
location_release(exprasmlist,left.location);
|
||||||
allocate_tempparaloc;
|
// allocate_tempparaloc;
|
||||||
{$ifdef i386}
|
{$ifdef i386}
|
||||||
if tempparaloc.loc<>LOC_REFERENCE then
|
if tempparaloc.loc<>LOC_REFERENCE then
|
||||||
internalerror(200309291);
|
internalerror(200309291);
|
||||||
@ -215,7 +215,6 @@ implementation
|
|||||||
aktcallnode.procdefinition.proccalloption) then
|
aktcallnode.procdefinition.proccalloption) then
|
||||||
begin
|
begin
|
||||||
location_release(exprasmlist,left.location);
|
location_release(exprasmlist,left.location);
|
||||||
allocate_tempparaloc;
|
|
||||||
{$ifdef i386}
|
{$ifdef i386}
|
||||||
if tempparaloc.loc<>LOC_REFERENCE then
|
if tempparaloc.loc<>LOC_REFERENCE then
|
||||||
internalerror(200309292);
|
internalerror(200309292);
|
||||||
@ -249,14 +248,14 @@ implementation
|
|||||||
if cgsize in [OS_64,OS_S64] then
|
if cgsize in [OS_64,OS_S64] then
|
||||||
begin
|
begin
|
||||||
inc(tcgcallnode(aktcallnode).pushedparasize,8);
|
inc(tcgcallnode(aktcallnode).pushedparasize,8);
|
||||||
allocate_tempparaloc;
|
// allocate_tempparaloc;
|
||||||
cg64.a_param64_loc(exprasmlist,left.location,tempparaloc);
|
cg64.a_param64_loc(exprasmlist,left.location,tempparaloc);
|
||||||
location_release(exprasmlist,left.location);
|
location_release(exprasmlist,left.location);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
location_release(exprasmlist,left.location);
|
location_release(exprasmlist,left.location);
|
||||||
allocate_tempparaloc;
|
// allocate_tempparaloc;
|
||||||
inc(tcgcallnode(aktcallnode).pushedparasize,align(tcgsize2size[tempparaloc.size],tempparaloc.alignment));
|
inc(tcgcallnode(aktcallnode).pushedparasize,align(tcgsize2size[tempparaloc.size],tempparaloc.alignment));
|
||||||
cg.a_param_loc(exprasmlist,left.location,tempparaloc);
|
cg.a_param_loc(exprasmlist,left.location,tempparaloc);
|
||||||
end;
|
end;
|
||||||
@ -266,7 +265,7 @@ implementation
|
|||||||
LOC_CMMXREGISTER:
|
LOC_CMMXREGISTER:
|
||||||
begin
|
begin
|
||||||
location_release(exprasmlist,left.location);
|
location_release(exprasmlist,left.location);
|
||||||
allocate_tempparaloc;
|
// allocate_tempparaloc;
|
||||||
inc(tcgcallnode(aktcallnode).pushedparasize,8);
|
inc(tcgcallnode(aktcallnode).pushedparasize,8);
|
||||||
cg.a_parammm_reg(exprasmlist,left.location.register);
|
cg.a_parammm_reg(exprasmlist,left.location.register);
|
||||||
end;
|
end;
|
||||||
@ -301,6 +300,8 @@ implementation
|
|||||||
objectlibrary.getlabel(falselabel);
|
objectlibrary.getlabel(falselabel);
|
||||||
secondpass(left);
|
secondpass(left);
|
||||||
|
|
||||||
|
allocate_tempparaloc;
|
||||||
|
|
||||||
{ handle varargs first, because paraitem.parasym is not valid }
|
{ handle varargs first, because paraitem.parasym is not valid }
|
||||||
if (nf_varargs_para in flags) then
|
if (nf_varargs_para in flags) then
|
||||||
begin
|
begin
|
||||||
@ -337,7 +338,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
|
inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
|
||||||
location_release(exprasmlist,left.location);
|
location_release(exprasmlist,left.location);
|
||||||
allocate_tempparaloc;
|
// allocate_tempparaloc;
|
||||||
cg.a_param_loc(exprasmlist,left.location,tempparaloc);
|
cg.a_param_loc(exprasmlist,left.location,tempparaloc);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -1129,7 +1130,13 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.145 2003-12-07 12:41:32 jonas
|
Revision 1.146 2003-12-15 21:25:48 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.145 2003/12/07 12:41:32 jonas
|
||||||
* fixed ansistring/widestring results: deallocate result reg only after
|
* fixed ansistring/widestring results: deallocate result reg only after
|
||||||
it has been stored to memory, as the storing itself may require extra
|
it has been stored to memory, as the storing itself may require extra
|
||||||
results (e.g. on ppc)
|
results (e.g. on ppc)
|
||||||
|
@ -526,26 +526,32 @@ implementation
|
|||||||
tt.def.needs_inittable) then
|
tt.def.needs_inittable) then
|
||||||
generate_inittable(newtype);
|
generate_inittable(newtype);
|
||||||
|
|
||||||
{ Always generate RTTI info for all types. This is to have typeinfo() return
|
|
||||||
the same pointer }
|
|
||||||
generate_rtti(newtype);
|
|
||||||
|
|
||||||
{ for objects we should write the vmt and interfaces.
|
{ for objects we should write the vmt and interfaces.
|
||||||
This need to be done after the rtti has been written, because
|
This need to be done after the rtti has been written, because
|
||||||
it can contain a reference to that data (PFV)
|
it can contain a reference to that data (PFV)
|
||||||
This is not for forward classes }
|
This is not for forward classes }
|
||||||
if (tt.def.deftype=objectdef) and
|
if (tt.def.deftype=objectdef) then
|
||||||
not(oo_is_forward in tobjectdef(tt.def).objectoptions) then
|
|
||||||
begin
|
begin
|
||||||
ch:=cclassheader.create(tobjectdef(tt.def));
|
if not(oo_is_forward in tobjectdef(tt.def).objectoptions) then
|
||||||
{ generate and check virtual methods, must be done
|
begin
|
||||||
before RTTI is written }
|
ch:=cclassheader.create(tobjectdef(tt.def));
|
||||||
ch.genvmt;
|
{ generate and check virtual methods, must be done
|
||||||
if is_interface(tobjectdef(tt.def)) then
|
before RTTI is written }
|
||||||
ch.writeinterfaceids;
|
ch.genvmt;
|
||||||
if (oo_has_vmt in tobjectdef(tt.def).objectoptions) then
|
{ Generate RTTI for class }
|
||||||
ch.writevmt;
|
generate_rtti(newtype);
|
||||||
ch.free;
|
if is_interface(tobjectdef(tt.def)) then
|
||||||
|
ch.writeinterfaceids;
|
||||||
|
if (oo_has_vmt in tobjectdef(tt.def).objectoptions) then
|
||||||
|
ch.writevmt;
|
||||||
|
ch.free;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{ Always generate RTTI info for all types. This is to have typeinfo() return
|
||||||
|
the same pointer }
|
||||||
|
generate_rtti(newtype);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
aktfilepos:=oldfilepos;
|
aktfilepos:=oldfilepos;
|
||||||
@ -656,7 +662,13 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.74 2003-12-12 12:09:40 marco
|
Revision 1.75 2003-12-15 21:25:48 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.74 2003/12/12 12:09:40 marco
|
||||||
* always generate RTTI patch from peter
|
* always generate RTTI patch from peter
|
||||||
|
|
||||||
Revision 1.73 2003/12/10 16:37:01 peter
|
Revision 1.73 2003/12/10 16:37:01 peter
|
||||||
|
@ -749,10 +749,7 @@ implementation
|
|||||||
|
|
||||||
{ The procedure body is finished, we can now
|
{ The procedure body is finished, we can now
|
||||||
allocate the registers }
|
allocate the registers }
|
||||||
if not(cs_no_regalloc in aktglobalswitches) then
|
cg.do_register_allocation(aktproccode,headertai);
|
||||||
begin
|
|
||||||
cg.do_register_allocation(aktproccode,headertai);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ Add save and restore of used registers }
|
{ Add save and restore of used registers }
|
||||||
aktfilepos:=entrypos;
|
aktfilepos:=entrypos;
|
||||||
@ -1333,7 +1330,13 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.176 2003-12-10 16:37:01 peter
|
Revision 1.177 2003-12-15 21:25:48 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.176 2003/12/10 16:37:01 peter
|
||||||
* global property support for fpc modes
|
* global property support for fpc modes
|
||||||
|
|
||||||
Revision 1.175 2003/12/03 23:13:20 peter
|
Revision 1.175 2003/12/03 23:13:20 peter
|
||||||
|
@ -146,6 +146,9 @@ unit rgobj;
|
|||||||
Treginfoflagset=set of Treginfoflag;
|
Treginfoflagset=set of Treginfoflag;
|
||||||
|
|
||||||
Treginfo=record
|
Treginfo=record
|
||||||
|
live_start,
|
||||||
|
live_end : Tai;
|
||||||
|
subreg : tsubregister;
|
||||||
alias : Tsuperregister;
|
alias : Tsuperregister;
|
||||||
{ The register allocator assigns each register a colour }
|
{ The register allocator assigns each register a colour }
|
||||||
colour : Tsuperregister;
|
colour : Tsuperregister;
|
||||||
@ -156,21 +159,6 @@ unit rgobj;
|
|||||||
end;
|
end;
|
||||||
Preginfo=^TReginfo;
|
Preginfo=^TReginfo;
|
||||||
|
|
||||||
{ This is the base class used for a register allocator. }
|
|
||||||
trgbase=class
|
|
||||||
function getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;virtual;abstract;
|
|
||||||
{# Get the register specified.}
|
|
||||||
procedure getexplicitregister(list:Taasmoutput;r:Tregister);virtual;abstract;
|
|
||||||
{# Get multiple registers specified.}
|
|
||||||
procedure allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;abstract;
|
|
||||||
{# Free multiple registers specified.}
|
|
||||||
procedure deallocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;abstract;
|
|
||||||
function uses_registers:boolean;virtual;abstract;
|
|
||||||
{# Deallocate any kind of register }
|
|
||||||
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;abstract;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{#------------------------------------------------------------------
|
{#------------------------------------------------------------------
|
||||||
|
|
||||||
This class implements the default register allocator. It is used by the
|
This class implements the default register allocator. It is used by the
|
||||||
@ -181,7 +169,7 @@ unit rgobj;
|
|||||||
by cpu-specific implementations.
|
by cpu-specific implementations.
|
||||||
|
|
||||||
--------------------------------------------------------------------}
|
--------------------------------------------------------------------}
|
||||||
trgobj=class(trgbase)
|
trgobj=class
|
||||||
preserved_by_proc : tcpuregisterset;
|
preserved_by_proc : tcpuregisterset;
|
||||||
used_in_proc : tcpuregisterset;
|
used_in_proc : tcpuregisterset;
|
||||||
// is_reg_var : Tsuperregisterset; {old regvars}
|
// is_reg_var : Tsuperregisterset; {old regvars}
|
||||||
@ -206,37 +194,18 @@ unit rgobj;
|
|||||||
function uses_registers:boolean;virtual;
|
function uses_registers:boolean;virtual;
|
||||||
{# Deallocate any kind of register }
|
{# Deallocate any kind of register }
|
||||||
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;
|
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;
|
||||||
procedure add_constraints(reg:Tregister);virtual;
|
procedure add_reg_instruction(instr:Tai;r:tregister);
|
||||||
|
procedure add_move_instruction(instr:Taicpu);
|
||||||
{# Do the register allocation.}
|
{# Do the register allocation.}
|
||||||
procedure do_register_allocation(list:Taasmoutput;headertai:tai);virtual;
|
procedure do_register_allocation(list:Taasmoutput;headertai:tai);virtual;
|
||||||
|
|
||||||
{ procedure resetusableregisters;virtual;}
|
|
||||||
|
|
||||||
{ procedure makeregvar(reg:Tsuperregister);}
|
|
||||||
|
|
||||||
{$ifdef EXTDEBUG}
|
|
||||||
procedure writegraph(loopidx:longint);
|
|
||||||
{$endif EXTDEBUG}
|
|
||||||
procedure add_move_instruction(instr:Taicpu);
|
|
||||||
{# Prepare the register colouring.}
|
|
||||||
procedure prepare_colouring;
|
|
||||||
{# Clean up after register colouring.}
|
|
||||||
procedure epilogue_colouring;
|
|
||||||
{# Colour the registers; that is do the register allocation.}
|
|
||||||
procedure colour_registers;
|
|
||||||
{# Spills certain registers in the specified assembler list.}
|
|
||||||
function spill_registers(list:Taasmoutput;headertai:tai):boolean;
|
|
||||||
procedure translate_registers(list:Taasmoutput);
|
|
||||||
{# Adds an interference edge.}
|
|
||||||
procedure add_edge(u,v:Tsuperregister);
|
|
||||||
procedure check_unreleasedregs;
|
|
||||||
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
regtype : Tregistertype;
|
regtype : Tregistertype;
|
||||||
{ default subregister used }
|
{ default subregister used }
|
||||||
defaultsub : tsubregister;
|
defaultsub : tsubregister;
|
||||||
|
{# Adds an interference edge.}
|
||||||
|
procedure add_edge(u,v:Tsuperregister);
|
||||||
|
procedure add_constraints(reg:Tregister);virtual;
|
||||||
|
private
|
||||||
{# First imaginary register.}
|
{# First imaginary register.}
|
||||||
first_imaginary : Tsuperregister;
|
first_imaginary : Tsuperregister;
|
||||||
{# Highest register allocated until now.}
|
{# Highest register allocated until now.}
|
||||||
@ -259,7 +228,21 @@ unit rgobj;
|
|||||||
coalesced_moves,
|
coalesced_moves,
|
||||||
constrained_moves : Tlinkedlist;
|
constrained_moves : Tlinkedlist;
|
||||||
live_registers:Tsuperregisterworklist;
|
live_registers:Tsuperregisterworklist;
|
||||||
function getnewreg:tsuperregister;
|
{$ifdef EXTDEBUG}
|
||||||
|
procedure writegraph(loopidx:longint);
|
||||||
|
{$endif EXTDEBUG}
|
||||||
|
{# Prepare the register colouring.}
|
||||||
|
procedure prepare_colouring;
|
||||||
|
{# Clean up after register colouring.}
|
||||||
|
procedure epilogue_colouring;
|
||||||
|
{# Colour the registers; that is do the register allocation.}
|
||||||
|
procedure colour_registers;
|
||||||
|
{# Spills certain registers in the specified assembler list.}
|
||||||
|
procedure insert_regalloc_info(list:Taasmoutput;headertai:tai);
|
||||||
|
procedure generate_interference_graph(list:Taasmoutput;headertai:tai);
|
||||||
|
procedure translate_registers(list:Taasmoutput);
|
||||||
|
function spill_registers(list:Taasmoutput;headertai:tai):boolean;
|
||||||
|
function getnewreg(subreg:tsubregister):tsuperregister;
|
||||||
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_edges_used(u:Tsuperregister);
|
procedure add_edges_used(u:Tsuperregister);
|
||||||
@ -429,7 +412,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function trgobj.getnewreg:tsuperregister;
|
function trgobj.getnewreg(subreg:tsubregister):tsuperregister;
|
||||||
var
|
var
|
||||||
oldmaxreginfo : tsuperregister;
|
oldmaxreginfo : tsuperregister;
|
||||||
begin
|
begin
|
||||||
@ -447,24 +430,16 @@ implementation
|
|||||||
{ Do we really need it to clear it ? At least for 1.0.x (PFV) }
|
{ Do we really need it to clear it ? At least for 1.0.x (PFV) }
|
||||||
fillchar(reginfo[oldmaxreginfo],(maxreginfo-oldmaxreginfo)*sizeof(treginfo),0);
|
fillchar(reginfo[oldmaxreginfo],(maxreginfo-oldmaxreginfo)*sizeof(treginfo),0);
|
||||||
end;
|
end;
|
||||||
|
reginfo[result].subreg:=subreg;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function trgobj.getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;
|
function trgobj.getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;
|
||||||
var
|
|
||||||
p : Tsuperregister;
|
|
||||||
r : Tregister;
|
|
||||||
begin
|
begin
|
||||||
p:=getnewreg;
|
|
||||||
live_registers.add(p);
|
|
||||||
if defaultsub=R_SUBNONE then
|
if defaultsub=R_SUBNONE then
|
||||||
r:=newreg(regtype,p,R_SUBNONE)
|
result:=newreg(regtype,getnewreg(R_SUBNONE),R_SUBNONE)
|
||||||
else
|
else
|
||||||
r:=newreg(regtype,p,subreg);
|
result:=newreg(regtype,getnewreg(subreg),subreg);
|
||||||
list.concat(Tai_regalloc.alloc(r));
|
|
||||||
add_edges_used(p);
|
|
||||||
add_constraints(r);
|
|
||||||
result:=r;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -475,29 +450,23 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
procedure trgobj.ungetregister(list:Taasmoutput;r:Tregister);
|
procedure trgobj.ungetregister(list:Taasmoutput;r:Tregister);
|
||||||
|
begin
|
||||||
var supreg:Tsuperregister;
|
{ Only explicit allocs insert regalloc info }
|
||||||
|
if getsupreg(r)<first_imaginary then
|
||||||
begin
|
list.concat(Tai_regalloc.dealloc(r));
|
||||||
supreg:=getsupreg(r);
|
end;
|
||||||
if live_registers.delete(supreg) then
|
|
||||||
list.concat(Tai_regalloc.dealloc(r));
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure trgobj.getexplicitregister(list:Taasmoutput;r:Tregister);
|
procedure trgobj.getexplicitregister(list:Taasmoutput;r:Tregister);
|
||||||
|
var
|
||||||
var supreg:Tsuperregister;
|
supreg:Tsuperregister;
|
||||||
|
begin
|
||||||
begin
|
supreg:=getsupreg(r);
|
||||||
supreg:=getsupreg(r);
|
if supreg>=first_imaginary then
|
||||||
live_registers.add(supreg);
|
internalerror(2003121503);
|
||||||
if supreg<first_imaginary then
|
|
||||||
include(used_in_proc,supreg);
|
include(used_in_proc,supreg);
|
||||||
list.concat(Tai_regalloc.alloc(r));
|
list.concat(Tai_regalloc.alloc(r));
|
||||||
add_edges_used(supreg);
|
end;
|
||||||
add_constraints(r);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure trgobj.allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);
|
procedure trgobj.allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);
|
||||||
@ -507,7 +476,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
for i:=0 to first_imaginary-1 do
|
for i:=0 to first_imaginary-1 do
|
||||||
if i in r then
|
if i in r then
|
||||||
getexplicitregister(list,i);
|
getexplicitregister(list,newreg(regtype,i,defaultsub));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -518,7 +487,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
for i:=0 to first_imaginary-1 do
|
for i:=0 to first_imaginary-1 do
|
||||||
if i in r then
|
if i in r then
|
||||||
ungetregister(list,i);
|
ungetregister(list,newreg(regtype,i,defaultsub));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -527,6 +496,12 @@ implementation
|
|||||||
spillingcounter:byte;
|
spillingcounter:byte;
|
||||||
endspill:boolean;
|
endspill:boolean;
|
||||||
begin
|
begin
|
||||||
|
{ Insert regalloc info for imaginary registers }
|
||||||
|
insert_regalloc_info(list,headertai);
|
||||||
|
generate_interference_graph(list,headertai);
|
||||||
|
{ Don't do the real allocation when -sr is passed }
|
||||||
|
if (cs_no_regalloc in aktglobalswitches) then
|
||||||
|
exit;
|
||||||
{Do register allocation.}
|
{Do register allocation.}
|
||||||
spillingcounter:=0;
|
spillingcounter:=0;
|
||||||
repeat
|
repeat
|
||||||
@ -542,6 +517,7 @@ implementation
|
|||||||
endspill:=not spill_registers(list,headertai);
|
endspill:=not spill_registers(list,headertai);
|
||||||
end;
|
end;
|
||||||
until endspill;
|
until endspill;
|
||||||
|
translate_registers(list);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -588,8 +564,9 @@ implementation
|
|||||||
var i:word;
|
var i:word;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
for i:=0 to live_registers.length-1 do
|
if live_registers.length>0 then
|
||||||
add_edge(u,live_registers.buf[i]);
|
for i:=0 to live_registers.length-1 do
|
||||||
|
add_edge(u,live_registers.buf[i]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$ifdef EXTDEBUG}
|
{$ifdef EXTDEBUG}
|
||||||
@ -644,6 +621,21 @@ implementation
|
|||||||
inc(reginfo[u].movelist^.count);
|
inc(reginfo[u].movelist^.count);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure trgobj.add_reg_instruction(instr:Tai;r:tregister);
|
||||||
|
var
|
||||||
|
supreg : tsuperregister;
|
||||||
|
begin
|
||||||
|
supreg:=getsupreg(r);
|
||||||
|
if supreg>=first_imaginary then
|
||||||
|
begin
|
||||||
|
if not assigned(reginfo[supreg].live_start) then
|
||||||
|
reginfo[supreg].live_start:=instr;
|
||||||
|
reginfo[supreg].live_end:=instr;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure trgobj.add_move_instruction(instr:Taicpu);
|
procedure trgobj.add_move_instruction(instr:Taicpu);
|
||||||
|
|
||||||
{This procedure notifies a certain as a move instruction so the
|
{This procedure notifies a certain as a move instruction so the
|
||||||
@ -827,8 +819,8 @@ implementation
|
|||||||
procedure trgobj.simplify;
|
procedure trgobj.simplify;
|
||||||
|
|
||||||
var adj : Psuperregisterworklist;
|
var adj : Psuperregisterworklist;
|
||||||
p,n : Tsuperregister;
|
n : Tsuperregister;
|
||||||
min,i:word;
|
i : word;
|
||||||
begin
|
begin
|
||||||
{We take the element with the least interferences out of the
|
{We take the element with the least interferences out of the
|
||||||
simplifyworklist. Since the simplifyworklist is now sorted, we
|
simplifyworklist. Since the simplifyworklist is now sorted, we
|
||||||
@ -1367,7 +1359,7 @@ implementation
|
|||||||
var p:Tsuperregister;
|
var p:Tsuperregister;
|
||||||
r:Tregister;
|
r:Tregister;
|
||||||
begin
|
begin
|
||||||
p:=getnewreg;
|
p:=getnewreg(subreg);
|
||||||
live_registers.add(p);
|
live_registers.add(p);
|
||||||
r:=newreg(regtype,p,subreg);
|
r:=newreg(regtype,p,subreg);
|
||||||
if position=nil then
|
if position=nil then
|
||||||
@ -1395,6 +1387,105 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure trgobj.insert_regalloc_info(list:Taasmoutput;headertai:tai);
|
||||||
|
var
|
||||||
|
supreg : tsuperregister;
|
||||||
|
p : tai;
|
||||||
|
r : tregister;
|
||||||
|
begin
|
||||||
|
{ Insert regallocs for all imaginary registers }
|
||||||
|
for supreg:=first_imaginary to maxreg-1 do
|
||||||
|
begin
|
||||||
|
r:=newreg(regtype,supreg,reginfo[supreg].subreg);
|
||||||
|
if assigned(reginfo[supreg].live_start) then
|
||||||
|
begin
|
||||||
|
{$ifdef EXTDEBUG}
|
||||||
|
if reginfo[supreg].live_start=reginfo[supreg].live_end then
|
||||||
|
Comment(V_Warning,'Register '+std_regname(r)+' is only used once');
|
||||||
|
{$endif EXTDEBUG}
|
||||||
|
list.insertbefore(Tai_regalloc.alloc(r),reginfo[supreg].live_start);
|
||||||
|
{ Insert live end deallocation before reg allocations
|
||||||
|
to reduce conflicts }
|
||||||
|
p:=reginfo[supreg].live_end;
|
||||||
|
while assigned(p) and
|
||||||
|
assigned(p.previous) and
|
||||||
|
(tai(p.previous).typ=ait_regalloc) and
|
||||||
|
tai_regalloc(p.previous).allocation do
|
||||||
|
p:=tai(p.previous);
|
||||||
|
list.insertbefore(Tai_regalloc.dealloc(r),p);
|
||||||
|
end
|
||||||
|
{$ifdef EXTDEBUG}
|
||||||
|
else
|
||||||
|
Comment(V_Warning,'Register '+std_regname(r)+' not used');
|
||||||
|
{$endif EXTDEBUG}
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure trgobj.generate_interference_graph(list:Taasmoutput;headertai:tai);
|
||||||
|
var
|
||||||
|
p : tai;
|
||||||
|
i : integer;
|
||||||
|
supreg : tsuperregister;
|
||||||
|
begin
|
||||||
|
{ All allocations are available. Now we can generate the
|
||||||
|
interference graph. Walk through all instructions, we can
|
||||||
|
start with the headertai, because before the header tai is
|
||||||
|
only symbols. }
|
||||||
|
live_registers.clear;
|
||||||
|
p:=headertai;
|
||||||
|
while assigned(p) do
|
||||||
|
begin
|
||||||
|
case p.typ of
|
||||||
|
ait_regalloc:
|
||||||
|
begin
|
||||||
|
if (getregtype(Tai_regalloc(p).reg)=regtype) then
|
||||||
|
begin
|
||||||
|
supreg:=getsupreg(Tai_regalloc(p).reg);
|
||||||
|
if Tai_regalloc(p).allocation then
|
||||||
|
live_registers.add(supreg)
|
||||||
|
else
|
||||||
|
live_registers.delete(supreg);
|
||||||
|
add_edges_used(supreg);
|
||||||
|
add_constraints(Tai_regalloc(p).reg);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{ ait_instruction:
|
||||||
|
begin
|
||||||
|
aktfilepos:=Taicpu_abstract(p).fileinfo;
|
||||||
|
for i:=0 to Taicpu_abstract(p).ops-1 do
|
||||||
|
with Taicpu_abstract(p).oper[i]^ do
|
||||||
|
begin
|
||||||
|
case typ of
|
||||||
|
top_reg :
|
||||||
|
begin
|
||||||
|
add_edges_used(getsupreg(reg));
|
||||||
|
add_constraints(reg);
|
||||||
|
end;
|
||||||
|
top_ref :
|
||||||
|
begin
|
||||||
|
add_edges_used(getsupreg(ref^.base));
|
||||||
|
add_constraints(ref^.base);
|
||||||
|
add_edges_used(getsupreg(ref^.index));
|
||||||
|
add_constraints(ref^.index);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end; }
|
||||||
|
end;
|
||||||
|
p:=Tai(p.next);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ifdef EXTDEBUG}
|
||||||
|
if live_registers.length>0 then
|
||||||
|
begin
|
||||||
|
for i:=0 to live_registers.length-1 do
|
||||||
|
Comment(V_Warning,'Register '+std_regname(newreg(R_INTREGISTER,live_registers.buf[i],defaultsub))+' not released');
|
||||||
|
end;
|
||||||
|
{$endif}
|
||||||
|
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.}
|
||||||
@ -1473,8 +1564,7 @@ implementation
|
|||||||
live_registers,
|
live_registers,
|
||||||
spill_temps^) then
|
spill_temps^) then
|
||||||
spill_registers:=true;
|
spill_registers:=true;
|
||||||
|
if Taicpu_abstract(p).is_reg_move then
|
||||||
if Taicpu_abstract(p).is_move then
|
|
||||||
add_move_instruction(Taicpu(p));
|
add_move_instruction(Taicpu(p));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1579,15 +1669,16 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure Trgobj.check_unreleasedregs;
|
|
||||||
begin
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.102 2003-12-15 16:37:47 daniel
|
Revision 1.103 2003-12-15 21:25:49 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.102 2003/12/15 16:37:47 daniel
|
||||||
* More microoptimizations
|
* More microoptimizations
|
||||||
|
|
||||||
Revision 1.101 2003/12/15 15:58:58 peter
|
Revision 1.101 2003/12/15 15:58:58 peter
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
**********************************************************************}
|
**********************************************************************}
|
||||||
|
{$mode objfpc}
|
||||||
{$i+}
|
{$i+}
|
||||||
program mkx86reg;
|
program mkx86reg;
|
||||||
|
|
||||||
@ -383,8 +384,8 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
first:=false;
|
first:=false;
|
||||||
writeln(confile,names[i],' = ',numbers[i],';');
|
writeln(confile,names[i],' = ','tregister(',numbers[i],')',';');
|
||||||
write(numfile,numbers[i]);
|
write(numfile,'tregister(',numbers[i],')');
|
||||||
write(stdfile,'''',stdnames[i],'''');
|
write(stdfile,'''',stdnames[i],'''');
|
||||||
write(attfile,'''',attnames[i],'''');
|
write(attfile,'''',attnames[i],'''');
|
||||||
if not(x86_64) then
|
if not(x86_64) then
|
||||||
@ -457,7 +458,13 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.3 2003-09-24 17:11:33 florian
|
Revision 1.4 2003-12-15 21:25:49 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.3 2003/09/24 17:11:33 florian
|
||||||
* x86_64 support; turn on by passing x86_64
|
* x86_64 support; turn on by passing x86_64
|
||||||
|
|
||||||
Revision 1.2 2003/09/03 15:55:02 peter
|
Revision 1.2 2003/09/03 15:55:02 peter
|
||||||
|
@ -201,7 +201,7 @@ interface
|
|||||||
procedure Pass2(sec:TAsmObjectdata);virtual;
|
procedure Pass2(sec:TAsmObjectdata);virtual;
|
||||||
procedure SetOperandOrder(order:TOperandOrder);
|
procedure SetOperandOrder(order:TOperandOrder);
|
||||||
function is_nop:boolean;override;
|
function is_nop:boolean;override;
|
||||||
function is_move:boolean;override;
|
function is_reg_move:boolean;override;
|
||||||
function spill_registers(list:Taasmoutput;
|
function spill_registers(list:Taasmoutput;
|
||||||
rgget:Trggetproc;
|
rgget:Trggetproc;
|
||||||
rgunget:Trgungetproc;
|
rgunget:Trgungetproc;
|
||||||
@ -1904,7 +1904,7 @@ implementation
|
|||||||
(opcode=A_XCHG) and (oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg) and (oper[0]^.reg=oper[1]^.reg);
|
(opcode=A_XCHG) and (oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg) and (oper[0]^.reg=oper[1]^.reg);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function Taicpu.is_move:boolean;
|
function Taicpu.is_reg_move:boolean;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
{We do not check the number of operands; we assume that nobody constructs
|
{We do not check the number of operands; we assume that nobody constructs
|
||||||
@ -1912,7 +1912,7 @@ implementation
|
|||||||
a move between a reference and a register is not a move that is of
|
a move between a reference and a register is not a move that is of
|
||||||
interrest to the register allocation, therefore we only return true
|
interrest to the register allocation, therefore we only return true
|
||||||
for a move between two registers. (DM)}
|
for a move between two registers. (DM)}
|
||||||
is_move:=((opcode=A_MOV) or (opcode=A_MOVZX) or (opcode=A_MOVSX)) and
|
result:=((opcode=A_MOV) or (opcode=A_MOVZX) or (opcode=A_MOVSX)) and
|
||||||
((oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg));
|
((oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2344,7 +2344,13 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.39 2003-12-14 20:24:28 daniel
|
Revision 1.40 2003-12-15 21:25:49 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.39 2003/12/14 20:24:28 daniel
|
||||||
* Register allocator speed optimizations
|
* Register allocator speed optimizations
|
||||||
- Worklist no longer a ringbuffer
|
- Worklist no longer a ringbuffer
|
||||||
- No find operations are left
|
- No find operations are left
|
||||||
|
@ -43,10 +43,10 @@ unit cgx86;
|
|||||||
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||||
procedure getexplicitregister(list:Taasmoutput;r:Tregister);override;
|
procedure getexplicitregister(list:Taasmoutput;r:Tregister);override;
|
||||||
procedure ungetregister(list:Taasmoutput;r:Tregister);override;
|
procedure ungetregister(list:Taasmoutput;r:Tregister);override;
|
||||||
procedure ungetreference(list:Taasmoutput;const r:Treference);override;
|
|
||||||
procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
|
procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
|
||||||
procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
|
procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
|
||||||
function uses_registers(rt:Tregistertype):boolean;override;
|
function uses_registers(rt:Tregistertype):boolean;override;
|
||||||
|
procedure add_reg_instruction(instr:Tai;r:tregister);override;
|
||||||
procedure dec_fpu_stack;
|
procedure dec_fpu_stack;
|
||||||
procedure inc_fpu_stack;
|
procedure inc_fpu_stack;
|
||||||
|
|
||||||
@ -211,15 +211,6 @@ unit cgx86;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcgx86.ungetreference(list:Taasmoutput;const r:Treference);
|
|
||||||
begin
|
|
||||||
if r.base<>NR_NO then
|
|
||||||
ungetregister(list,r.base);
|
|
||||||
if r.index<>NR_NO then
|
|
||||||
ungetregister(list,r.index);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure Tcgx86.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
|
procedure Tcgx86.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
|
||||||
begin
|
begin
|
||||||
if rt<>R_FPUREGISTER then
|
if rt<>R_FPUREGISTER then
|
||||||
@ -243,6 +234,13 @@ unit cgx86;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcgx86.add_reg_instruction(instr:Tai;r:tregister);
|
||||||
|
begin
|
||||||
|
if getregtype(r)<>R_FPUREGISTER then
|
||||||
|
inherited add_reg_instruction(instr,r);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcgx86.dec_fpu_stack;
|
procedure tcgx86.dec_fpu_stack;
|
||||||
begin
|
begin
|
||||||
dec(rgfpu.fpuvaroffset);
|
dec(rgfpu.fpuvaroffset);
|
||||||
@ -1426,18 +1424,18 @@ unit cgx86;
|
|||||||
system_i386_win32,
|
system_i386_win32,
|
||||||
{$endif}
|
{$endif}
|
||||||
system_i386_freebsd,
|
system_i386_freebsd,
|
||||||
system_i386_netbsd,
|
system_i386_netbsd,
|
||||||
// system_i386_openbsd,
|
// system_i386_openbsd,
|
||||||
system_i386_wdosx,
|
system_i386_wdosx,
|
||||||
system_i386_linux:
|
system_i386_linux:
|
||||||
begin
|
begin
|
||||||
Case target_info.system Of
|
Case target_info.system Of
|
||||||
system_i386_freebsd : mcountprefix:='.';
|
system_i386_freebsd : mcountprefix:='.';
|
||||||
system_i386_netbsd : mcountprefix:='__';
|
system_i386_netbsd : mcountprefix:='__';
|
||||||
// system_i386_openbsd : mcountprefix:='.';
|
// system_i386_openbsd : mcountprefix:='.';
|
||||||
else
|
else
|
||||||
mcountPrefix:='';
|
mcountPrefix:='';
|
||||||
end;
|
end;
|
||||||
objectlibrary.getaddrlabel(pl);
|
objectlibrary.getaddrlabel(pl);
|
||||||
list.concat(Tai_section.Create(sec_data));
|
list.concat(Tai_section.Create(sec_data));
|
||||||
list.concat(Tai_align.Create(4));
|
list.concat(Tai_align.Create(4));
|
||||||
@ -1684,7 +1682,13 @@ unit cgx86;
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.90 2003-12-12 17:16:18 peter
|
Revision 1.91 2003-12-15 21:25:49 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.90 2003/12/12 17:16:18 peter
|
||||||
* rg[tregistertype] added in tcg
|
* rg[tregistertype] added in tcg
|
||||||
|
|
||||||
Revision 1.89 2003/12/06 01:15:23 florian
|
Revision 1.89 2003/12/06 01:15:23 florian
|
||||||
|
@ -176,7 +176,7 @@ uses
|
|||||||
{$endif x86_64}
|
{$endif x86_64}
|
||||||
);
|
);
|
||||||
|
|
||||||
regstabs_table : array[tregisterindex] of tregister = (
|
regstabs_table : array[tregisterindex] of shortint = (
|
||||||
{$ifdef x86_64}
|
{$ifdef x86_64}
|
||||||
{$i r8664stab.inc}
|
{$i r8664stab.inc}
|
||||||
{$else x86_64}
|
{$else x86_64}
|
||||||
@ -526,7 +526,13 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.30 2003-10-31 09:22:55 mazen
|
Revision 1.31 2003-12-15 21:25:49 peter
|
||||||
|
* reg allocations for imaginary register are now inserted just
|
||||||
|
before reg allocation
|
||||||
|
* tregister changed to enum to allow compile time check
|
||||||
|
* fixed several tregister-tsuperregister errors
|
||||||
|
|
||||||
|
Revision 1.30 2003/10/31 09:22:55 mazen
|
||||||
* using findreg_by_<name|number>_table directly to decrease heap overheading
|
* using findreg_by_<name|number>_table directly to decrease heap overheading
|
||||||
|
|
||||||
Revision 1.29 2003/10/30 17:13:18 peter
|
Revision 1.29 2003/10/30 17:13:18 peter
|
||||||
|
Loading…
Reference in New Issue
Block a user