mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-10 23:20:29 +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;
|
||||
|
||||
tadd_reg_instruction_proc=procedure(instr:Tai;r: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;
|
||||
|
||||
@ -491,7 +492,7 @@ interface
|
||||
procedure loadoper(opidx:longint;o:toper);
|
||||
procedure clearop(opidx:longint);
|
||||
function is_nop:boolean;virtual;abstract;
|
||||
function is_move:boolean;virtual;abstract;
|
||||
function is_reg_move:boolean;virtual;abstract;
|
||||
{ register allocator }
|
||||
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);
|
||||
@ -542,6 +543,9 @@ interface
|
||||
{ label when the result is true or false }
|
||||
truelabel,falselabel : tasmlabel;
|
||||
|
||||
{ hook to notify uses of registers }
|
||||
add_reg_instruction_hook : tadd_reg_instruction_proc;
|
||||
|
||||
{ default lists }
|
||||
datasegment,codesegment,bsssegment,
|
||||
debuglist,withdebuglist,consts,
|
||||
@ -1677,6 +1681,8 @@ implementation
|
||||
segprefix:=ref^.segment;
|
||||
{$endif}
|
||||
typ:=top_ref;
|
||||
add_reg_instruction_hook(self,ref^.base);
|
||||
add_reg_instruction_hook(self,ref^.index);
|
||||
{ mark symbol as used }
|
||||
if assigned(ref^.symbol) then
|
||||
ref^.symbol.increfs;
|
||||
@ -1694,6 +1700,7 @@ implementation
|
||||
reg:=r;
|
||||
typ:=top_reg;
|
||||
end;
|
||||
add_reg_instruction_hook(self,r);
|
||||
{$ifdef ARM}
|
||||
{ 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.
|
||||
@ -1714,10 +1721,14 @@ implementation
|
||||
with oper[opidx]^ do
|
||||
begin
|
||||
case typ of
|
||||
top_reg:
|
||||
add_reg_instruction_hook(self,reg);
|
||||
top_ref:
|
||||
begin
|
||||
new(ref);
|
||||
ref^:=o.ref^;
|
||||
add_reg_instruction_hook(self,ref^.base);
|
||||
add_reg_instruction_hook(self,ref^.index);
|
||||
end;
|
||||
{$ifdef ARM}
|
||||
top_shifterop:
|
||||
@ -2202,7 +2213,13 @@ implementation
|
||||
end.
|
||||
{
|
||||
$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
|
||||
- Worklist no longer a ringbuffer
|
||||
- No find operations are left
|
||||
|
@ -133,12 +133,17 @@ interface
|
||||
{
|
||||
The new register coding:
|
||||
|
||||
SuperRegister (bits 0..7)
|
||||
Unused (bits 8..15)
|
||||
SuperRegister (bits 0..15)
|
||||
Subregister (bits 16..23)
|
||||
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
|
||||
{$ifdef FPC_BIG_ENDIAN}
|
||||
regtype : Tregistertype;
|
||||
@ -316,7 +321,7 @@ implementation
|
||||
end;
|
||||
|
||||
destructor tsuperregisterworklist.done;
|
||||
|
||||
|
||||
begin
|
||||
if assigned(buf) then
|
||||
freemem(buf);
|
||||
@ -324,7 +329,7 @@ implementation
|
||||
|
||||
|
||||
procedure tsuperregisterworklist.add(s:tsuperregister);
|
||||
|
||||
|
||||
begin
|
||||
inc(length);
|
||||
{ Need to increase buffer length? }
|
||||
@ -341,14 +346,14 @@ implementation
|
||||
|
||||
|
||||
procedure tsuperregisterworklist.clear;
|
||||
|
||||
|
||||
begin
|
||||
length:=0;
|
||||
end;
|
||||
|
||||
|
||||
procedure tsuperregisterworklist.deleteidx(i:word);
|
||||
|
||||
|
||||
begin
|
||||
if length=0 then
|
||||
internalerror(200310144);
|
||||
@ -358,7 +363,7 @@ implementation
|
||||
|
||||
|
||||
function tsuperregisterworklist.get:tsuperregister;
|
||||
|
||||
|
||||
begin
|
||||
if length=0 then
|
||||
internalerror(200310142);
|
||||
@ -369,9 +374,9 @@ implementation
|
||||
|
||||
|
||||
function tsuperregisterworklist.delete(s:tsuperregister):boolean;
|
||||
|
||||
|
||||
var i:word;
|
||||
|
||||
|
||||
begin
|
||||
delete:=false;
|
||||
for i:=1 to length do
|
||||
@ -569,7 +574,13 @@ finalization
|
||||
end.
|
||||
{
|
||||
$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
|
||||
- Worklist no longer a ringbuffer
|
||||
- No find operations are left
|
||||
|
@ -84,6 +84,7 @@ unit cgobj;
|
||||
procedure ungetregister(list:Taasmoutput;r:Tregister);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;
|
||||
|
||||
function uses_registers(rt:Tregistertype):boolean;virtual;
|
||||
@ -553,6 +554,7 @@ implementation
|
||||
|
||||
constructor tcg.create;
|
||||
begin
|
||||
add_reg_instruction_hook:={$ifdef FPCPROCVAR}@{$endif}add_reg_instruction;
|
||||
end;
|
||||
|
||||
|
||||
@ -627,6 +629,8 @@ implementation
|
||||
begin
|
||||
if r.base<>NR_NO then
|
||||
ungetregister(list,r.base);
|
||||
if r.index<>NR_NO then
|
||||
ungetregister(list,r.index);
|
||||
end;
|
||||
|
||||
|
||||
@ -657,6 +661,19 @@ implementation
|
||||
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);
|
||||
var
|
||||
rt : tregistertype;
|
||||
@ -676,11 +693,7 @@ implementation
|
||||
for rt:=low(tregistertype) to high(tregistertype) do
|
||||
begin
|
||||
if assigned(rg[rt]) then
|
||||
begin
|
||||
rg[rt].check_unreleasedregs;
|
||||
rg[rt].do_register_allocation(list,headertai);
|
||||
rg[rt].translate_registers(list);
|
||||
end;
|
||||
rg[rt].do_register_allocation(list,headertai);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1941,7 +1954,13 @@ finalization
|
||||
end.
|
||||
{
|
||||
$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
|
||||
|
||||
Revision 1.137 2003/12/06 22:11:47 jonas
|
||||
|
@ -178,7 +178,7 @@ begin
|
||||
tmpRef.base := NR_EDI;
|
||||
tmpRef.index := NR_EDI;
|
||||
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
|
||||
exclude(regsStillValid,regCounter);
|
||||
modifiesConflictingMemLocation := not(supreg in regsStillValid);
|
||||
@ -1954,7 +1954,7 @@ begin
|
||||
if (memreg <> NR_NO) and
|
||||
(not getNextInstruction(p,hp1) or
|
||||
(RegLoadedWithNewValue(getsupreg(memreg),false,hp1) or
|
||||
FindRegDealloc(getsupreg(regcounter),hp1))) then
|
||||
FindRegDealloc(regcounter,hp1))) then
|
||||
begin
|
||||
hp1 := Tai_Marker.Create(NoPropInfoEnd);
|
||||
insertllitem(asml,p,p.next,hp1);
|
||||
@ -2074,7 +2074,13 @@ end.
|
||||
|
||||
{
|
||||
$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
|
||||
parameters are released before a call
|
||||
* fix storeback of registers in case of different sizes (e.g., first
|
||||
|
@ -1785,7 +1785,7 @@ begin
|
||||
(typ in [con_ref,con_noRemoveRef]) and
|
||||
(not(cs_UncertainOpts in aktglobalswitches) or
|
||||
{ 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 }
|
||||
containsPointerLoad(c)
|
||||
);
|
||||
@ -1963,7 +1963,7 @@ var
|
||||
p, prev: tai;
|
||||
hp1, hp2: tai;
|
||||
{$ifdef i386}
|
||||
regcounter: tregister;
|
||||
regcounter,
|
||||
supreg : tsuperregister;
|
||||
{$endif i386}
|
||||
usedregs, nodeallocregs: tregset;
|
||||
@ -2052,7 +2052,7 @@ begin
|
||||
usedRegs := usedRegs - noDeallocRegs;
|
||||
for regCounter := RS_EAX to RS_EDI do
|
||||
if regCounter in usedRegs then
|
||||
addRegDeallocFor(list,regCounter,prev);
|
||||
addRegDeallocFor(list,newreg(R_INTREGISTER,regCounter,R_SUBWHOLE),prev);
|
||||
{$endif i386}
|
||||
end;
|
||||
|
||||
@ -2714,7 +2714,13 @@ end.
|
||||
|
||||
{
|
||||
$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
|
||||
|
||||
Revision 1.59 2003/12/14 22:42:14 peter
|
||||
|
@ -1808,7 +1808,7 @@ begin
|
||||
TmpUsedRegs := UsedRegs;
|
||||
UpdateUsedRegs(TmpUsedRegs,tai(hp1.next));
|
||||
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
|
||||
{ change mov (ref), reg }
|
||||
{ add/sub/or/... reg2/$const, reg }
|
||||
@ -1996,7 +1996,13 @@ end.
|
||||
|
||||
{
|
||||
$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
|
||||
|
||||
Revision 1.51 2003/12/13 15:48:47 jonas
|
||||
|
@ -1,72 +1,72 @@
|
||||
{ don't edit, this file is generated from x86reg.dat }
|
||||
NR_NO = $00000000;
|
||||
NR_AL = $01010000;
|
||||
NR_AH = $01020000;
|
||||
NR_AX = $01030000;
|
||||
NR_EAX = $01040000;
|
||||
NR_CL = $01010001;
|
||||
NR_CH = $01020001;
|
||||
NR_CX = $01030001;
|
||||
NR_ECX = $01040001;
|
||||
NR_DL = $01010002;
|
||||
NR_DH = $01020002;
|
||||
NR_DX = $01030002;
|
||||
NR_EDX = $01040002;
|
||||
NR_BL = $01010003;
|
||||
NR_BH = $01020003;
|
||||
NR_BX = $01030003;
|
||||
NR_EBX = $01040003;
|
||||
NR_SI = $01030004;
|
||||
NR_ESI = $01040004;
|
||||
NR_DI = $01030005;
|
||||
NR_EDI = $01040005;
|
||||
NR_BP = $01030006;
|
||||
NR_EBP = $01040006;
|
||||
NR_SP = $01030007;
|
||||
NR_ESP = $01040007;
|
||||
NR_CS = $05000001;
|
||||
NR_DS = $05000002;
|
||||
NR_ES = $05000003;
|
||||
NR_SS = $05000004;
|
||||
NR_FS = $05000005;
|
||||
NR_GS = $05000006;
|
||||
NR_DR0 = $05000007;
|
||||
NR_DR1 = $05000008;
|
||||
NR_DR2 = $05000009;
|
||||
NR_DR3 = $0500000a;
|
||||
NR_DR6 = $0500000b;
|
||||
NR_DR7 = $0500000c;
|
||||
NR_CR0 = $0500000d;
|
||||
NR_CR2 = $0500000e;
|
||||
NR_CR3 = $0500000f;
|
||||
NR_CR4 = $05000010;
|
||||
NR_TR3 = $05000011;
|
||||
NR_TR4 = $05000012;
|
||||
NR_TR5 = $05000013;
|
||||
NR_TR6 = $05000014;
|
||||
NR_TR7 = $05000015;
|
||||
NR_ST0 = $02000000;
|
||||
NR_ST1 = $02000001;
|
||||
NR_ST2 = $02000002;
|
||||
NR_ST3 = $02000003;
|
||||
NR_ST4 = $02000004;
|
||||
NR_ST5 = $02000005;
|
||||
NR_ST6 = $02000006;
|
||||
NR_ST7 = $02000007;
|
||||
NR_ST = $02000008;
|
||||
NR_MM0 = $03000000;
|
||||
NR_MM1 = $03000001;
|
||||
NR_MM2 = $03000002;
|
||||
NR_MM3 = $03000003;
|
||||
NR_MM4 = $03000004;
|
||||
NR_MM5 = $03000005;
|
||||
NR_MM6 = $03000006;
|
||||
NR_MM7 = $03000007;
|
||||
NR_XMM0 = $04000000;
|
||||
NR_XMM1 = $04000001;
|
||||
NR_XMM2 = $04000002;
|
||||
NR_XMM3 = $04000003;
|
||||
NR_XMM4 = $04000004;
|
||||
NR_XMM5 = $04000005;
|
||||
NR_XMM6 = $04000006;
|
||||
NR_XMM7 = $04000007;
|
||||
NR_NO = tregister($00000000);
|
||||
NR_AL = tregister($01010000);
|
||||
NR_AH = tregister($01020000);
|
||||
NR_AX = tregister($01030000);
|
||||
NR_EAX = tregister($01040000);
|
||||
NR_CL = tregister($01010001);
|
||||
NR_CH = tregister($01020001);
|
||||
NR_CX = tregister($01030001);
|
||||
NR_ECX = tregister($01040001);
|
||||
NR_DL = tregister($01010002);
|
||||
NR_DH = tregister($01020002);
|
||||
NR_DX = tregister($01030002);
|
||||
NR_EDX = tregister($01040002);
|
||||
NR_BL = tregister($01010003);
|
||||
NR_BH = tregister($01020003);
|
||||
NR_BX = tregister($01030003);
|
||||
NR_EBX = tregister($01040003);
|
||||
NR_SI = tregister($01030004);
|
||||
NR_ESI = tregister($01040004);
|
||||
NR_DI = tregister($01030005);
|
||||
NR_EDI = tregister($01040005);
|
||||
NR_BP = tregister($01030006);
|
||||
NR_EBP = tregister($01040006);
|
||||
NR_SP = tregister($01030007);
|
||||
NR_ESP = tregister($01040007);
|
||||
NR_CS = tregister($05000001);
|
||||
NR_DS = tregister($05000002);
|
||||
NR_ES = tregister($05000003);
|
||||
NR_SS = tregister($05000004);
|
||||
NR_FS = tregister($05000005);
|
||||
NR_GS = tregister($05000006);
|
||||
NR_DR0 = tregister($05000007);
|
||||
NR_DR1 = tregister($05000008);
|
||||
NR_DR2 = tregister($05000009);
|
||||
NR_DR3 = tregister($0500000a);
|
||||
NR_DR6 = tregister($0500000b);
|
||||
NR_DR7 = tregister($0500000c);
|
||||
NR_CR0 = tregister($0500000d);
|
||||
NR_CR2 = tregister($0500000e);
|
||||
NR_CR3 = tregister($0500000f);
|
||||
NR_CR4 = tregister($05000010);
|
||||
NR_TR3 = tregister($05000011);
|
||||
NR_TR4 = tregister($05000012);
|
||||
NR_TR5 = tregister($05000013);
|
||||
NR_TR6 = tregister($05000014);
|
||||
NR_TR7 = tregister($05000015);
|
||||
NR_ST0 = tregister($02000000);
|
||||
NR_ST1 = tregister($02000001);
|
||||
NR_ST2 = tregister($02000002);
|
||||
NR_ST3 = tregister($02000003);
|
||||
NR_ST4 = tregister($02000004);
|
||||
NR_ST5 = tregister($02000005);
|
||||
NR_ST6 = tregister($02000006);
|
||||
NR_ST7 = tregister($02000007);
|
||||
NR_ST = tregister($02000008);
|
||||
NR_MM0 = tregister($03000000);
|
||||
NR_MM1 = tregister($03000001);
|
||||
NR_MM2 = tregister($03000002);
|
||||
NR_MM3 = tregister($03000003);
|
||||
NR_MM4 = tregister($03000004);
|
||||
NR_MM5 = tregister($03000005);
|
||||
NR_MM6 = tregister($03000006);
|
||||
NR_MM7 = tregister($03000007);
|
||||
NR_XMM0 = tregister($04000000);
|
||||
NR_XMM1 = tregister($04000001);
|
||||
NR_XMM2 = tregister($04000002);
|
||||
NR_XMM3 = tregister($04000003);
|
||||
NR_XMM4 = tregister($04000004);
|
||||
NR_XMM5 = tregister($04000005);
|
||||
NR_XMM6 = tregister($04000006);
|
||||
NR_XMM7 = tregister($04000007);
|
||||
|
@ -1,72 +1,72 @@
|
||||
{ don't edit, this file is generated from x86reg.dat }
|
||||
$00000000,
|
||||
$01010000,
|
||||
$01020000,
|
||||
$01030000,
|
||||
$01040000,
|
||||
$01010001,
|
||||
$01020001,
|
||||
$01030001,
|
||||
$01040001,
|
||||
$01010002,
|
||||
$01020002,
|
||||
$01030002,
|
||||
$01040002,
|
||||
$01010003,
|
||||
$01020003,
|
||||
$01030003,
|
||||
$01040003,
|
||||
$01030004,
|
||||
$01040004,
|
||||
$01030005,
|
||||
$01040005,
|
||||
$01030006,
|
||||
$01040006,
|
||||
$01030007,
|
||||
$01040007,
|
||||
$05000001,
|
||||
$05000002,
|
||||
$05000003,
|
||||
$05000004,
|
||||
$05000005,
|
||||
$05000006,
|
||||
$05000007,
|
||||
$05000008,
|
||||
$05000009,
|
||||
$0500000a,
|
||||
$0500000b,
|
||||
$0500000c,
|
||||
$0500000d,
|
||||
$0500000e,
|
||||
$0500000f,
|
||||
$05000010,
|
||||
$05000011,
|
||||
$05000012,
|
||||
$05000013,
|
||||
$05000014,
|
||||
$05000015,
|
||||
$02000000,
|
||||
$02000001,
|
||||
$02000002,
|
||||
$02000003,
|
||||
$02000004,
|
||||
$02000005,
|
||||
$02000006,
|
||||
$02000007,
|
||||
$02000008,
|
||||
$03000000,
|
||||
$03000001,
|
||||
$03000002,
|
||||
$03000003,
|
||||
$03000004,
|
||||
$03000005,
|
||||
$03000006,
|
||||
$03000007,
|
||||
$04000000,
|
||||
$04000001,
|
||||
$04000002,
|
||||
$04000003,
|
||||
$04000004,
|
||||
$04000005,
|
||||
$04000006,
|
||||
$04000007
|
||||
tregister($00000000),
|
||||
tregister($01010000),
|
||||
tregister($01020000),
|
||||
tregister($01030000),
|
||||
tregister($01040000),
|
||||
tregister($01010001),
|
||||
tregister($01020001),
|
||||
tregister($01030001),
|
||||
tregister($01040001),
|
||||
tregister($01010002),
|
||||
tregister($01020002),
|
||||
tregister($01030002),
|
||||
tregister($01040002),
|
||||
tregister($01010003),
|
||||
tregister($01020003),
|
||||
tregister($01030003),
|
||||
tregister($01040003),
|
||||
tregister($01030004),
|
||||
tregister($01040004),
|
||||
tregister($01030005),
|
||||
tregister($01040005),
|
||||
tregister($01030006),
|
||||
tregister($01040006),
|
||||
tregister($01030007),
|
||||
tregister($01040007),
|
||||
tregister($05000001),
|
||||
tregister($05000002),
|
||||
tregister($05000003),
|
||||
tregister($05000004),
|
||||
tregister($05000005),
|
||||
tregister($05000006),
|
||||
tregister($05000007),
|
||||
tregister($05000008),
|
||||
tregister($05000009),
|
||||
tregister($0500000a),
|
||||
tregister($0500000b),
|
||||
tregister($0500000c),
|
||||
tregister($0500000d),
|
||||
tregister($0500000e),
|
||||
tregister($0500000f),
|
||||
tregister($05000010),
|
||||
tregister($05000011),
|
||||
tregister($05000012),
|
||||
tregister($05000013),
|
||||
tregister($05000014),
|
||||
tregister($05000015),
|
||||
tregister($02000000),
|
||||
tregister($02000001),
|
||||
tregister($02000002),
|
||||
tregister($02000003),
|
||||
tregister($02000004),
|
||||
tregister($02000005),
|
||||
tregister($02000006),
|
||||
tregister($02000007),
|
||||
tregister($02000008),
|
||||
tregister($03000000),
|
||||
tregister($03000001),
|
||||
tregister($03000002),
|
||||
tregister($03000003),
|
||||
tregister($03000004),
|
||||
tregister($03000005),
|
||||
tregister($03000006),
|
||||
tregister($03000007),
|
||||
tregister($04000000),
|
||||
tregister($04000001),
|
||||
tregister($04000002),
|
||||
tregister($04000003),
|
||||
tregister($04000004),
|
||||
tregister($04000005),
|
||||
tregister($04000006),
|
||||
tregister($04000007)
|
||||
|
@ -113,7 +113,7 @@ implementation
|
||||
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
||||
internalerror(200304235);
|
||||
location_release(exprasmlist,left.location);
|
||||
allocate_tempparaloc;
|
||||
// allocate_tempparaloc;
|
||||
cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
|
||||
inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
|
||||
end;
|
||||
@ -137,7 +137,7 @@ implementation
|
||||
if left.resulttype.def.deftype=floatdef then
|
||||
begin
|
||||
location_release(exprasmlist,left.location);
|
||||
allocate_tempparaloc;
|
||||
// allocate_tempparaloc;
|
||||
{$ifdef i386}
|
||||
if tempparaloc.loc<>LOC_REFERENCE then
|
||||
internalerror(200309291);
|
||||
@ -215,7 +215,6 @@ implementation
|
||||
aktcallnode.procdefinition.proccalloption) then
|
||||
begin
|
||||
location_release(exprasmlist,left.location);
|
||||
allocate_tempparaloc;
|
||||
{$ifdef i386}
|
||||
if tempparaloc.loc<>LOC_REFERENCE then
|
||||
internalerror(200309292);
|
||||
@ -249,14 +248,14 @@ implementation
|
||||
if cgsize in [OS_64,OS_S64] then
|
||||
begin
|
||||
inc(tcgcallnode(aktcallnode).pushedparasize,8);
|
||||
allocate_tempparaloc;
|
||||
// allocate_tempparaloc;
|
||||
cg64.a_param64_loc(exprasmlist,left.location,tempparaloc);
|
||||
location_release(exprasmlist,left.location);
|
||||
end
|
||||
else
|
||||
begin
|
||||
location_release(exprasmlist,left.location);
|
||||
allocate_tempparaloc;
|
||||
// allocate_tempparaloc;
|
||||
inc(tcgcallnode(aktcallnode).pushedparasize,align(tcgsize2size[tempparaloc.size],tempparaloc.alignment));
|
||||
cg.a_param_loc(exprasmlist,left.location,tempparaloc);
|
||||
end;
|
||||
@ -266,7 +265,7 @@ implementation
|
||||
LOC_CMMXREGISTER:
|
||||
begin
|
||||
location_release(exprasmlist,left.location);
|
||||
allocate_tempparaloc;
|
||||
// allocate_tempparaloc;
|
||||
inc(tcgcallnode(aktcallnode).pushedparasize,8);
|
||||
cg.a_parammm_reg(exprasmlist,left.location.register);
|
||||
end;
|
||||
@ -301,6 +300,8 @@ implementation
|
||||
objectlibrary.getlabel(falselabel);
|
||||
secondpass(left);
|
||||
|
||||
allocate_tempparaloc;
|
||||
|
||||
{ handle varargs first, because paraitem.parasym is not valid }
|
||||
if (nf_varargs_para in flags) then
|
||||
begin
|
||||
@ -337,7 +338,7 @@ implementation
|
||||
begin
|
||||
inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
|
||||
location_release(exprasmlist,left.location);
|
||||
allocate_tempparaloc;
|
||||
// allocate_tempparaloc;
|
||||
cg.a_param_loc(exprasmlist,left.location,tempparaloc);
|
||||
end
|
||||
else
|
||||
@ -1129,7 +1130,13 @@ begin
|
||||
end.
|
||||
{
|
||||
$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
|
||||
it has been stored to memory, as the storing itself may require extra
|
||||
results (e.g. on ppc)
|
||||
|
@ -526,26 +526,32 @@ implementation
|
||||
tt.def.needs_inittable) then
|
||||
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.
|
||||
This need to be done after the rtti has been written, because
|
||||
it can contain a reference to that data (PFV)
|
||||
This is not for forward classes }
|
||||
if (tt.def.deftype=objectdef) and
|
||||
not(oo_is_forward in tobjectdef(tt.def).objectoptions) then
|
||||
if (tt.def.deftype=objectdef) then
|
||||
begin
|
||||
ch:=cclassheader.create(tobjectdef(tt.def));
|
||||
{ generate and check virtual methods, must be done
|
||||
before RTTI is written }
|
||||
ch.genvmt;
|
||||
if is_interface(tobjectdef(tt.def)) then
|
||||
ch.writeinterfaceids;
|
||||
if (oo_has_vmt in tobjectdef(tt.def).objectoptions) then
|
||||
ch.writevmt;
|
||||
ch.free;
|
||||
if not(oo_is_forward in tobjectdef(tt.def).objectoptions) then
|
||||
begin
|
||||
ch:=cclassheader.create(tobjectdef(tt.def));
|
||||
{ generate and check virtual methods, must be done
|
||||
before RTTI is written }
|
||||
ch.genvmt;
|
||||
{ Generate RTTI for class }
|
||||
generate_rtti(newtype);
|
||||
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;
|
||||
|
||||
aktfilepos:=oldfilepos;
|
||||
@ -656,7 +662,13 @@ implementation
|
||||
end.
|
||||
{
|
||||
$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
|
||||
|
||||
Revision 1.73 2003/12/10 16:37:01 peter
|
||||
|
@ -749,10 +749,7 @@ implementation
|
||||
|
||||
{ The procedure body is finished, we can now
|
||||
allocate the registers }
|
||||
if not(cs_no_regalloc in aktglobalswitches) then
|
||||
begin
|
||||
cg.do_register_allocation(aktproccode,headertai);
|
||||
end;
|
||||
cg.do_register_allocation(aktproccode,headertai);
|
||||
|
||||
{ Add save and restore of used registers }
|
||||
aktfilepos:=entrypos;
|
||||
@ -1333,7 +1330,13 @@ implementation
|
||||
end.
|
||||
{
|
||||
$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
|
||||
|
||||
Revision 1.175 2003/12/03 23:13:20 peter
|
||||
|
@ -146,6 +146,9 @@ unit rgobj;
|
||||
Treginfoflagset=set of Treginfoflag;
|
||||
|
||||
Treginfo=record
|
||||
live_start,
|
||||
live_end : Tai;
|
||||
subreg : tsubregister;
|
||||
alias : Tsuperregister;
|
||||
{ The register allocator assigns each register a colour }
|
||||
colour : Tsuperregister;
|
||||
@ -156,21 +159,6 @@ unit rgobj;
|
||||
end;
|
||||
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
|
||||
@ -181,7 +169,7 @@ unit rgobj;
|
||||
by cpu-specific implementations.
|
||||
|
||||
--------------------------------------------------------------------}
|
||||
trgobj=class(trgbase)
|
||||
trgobj=class
|
||||
preserved_by_proc : tcpuregisterset;
|
||||
used_in_proc : tcpuregisterset;
|
||||
// is_reg_var : Tsuperregisterset; {old regvars}
|
||||
@ -206,37 +194,18 @@ unit rgobj;
|
||||
function uses_registers:boolean;virtual;
|
||||
{# Deallocate any kind of register }
|
||||
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.}
|
||||
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
|
||||
regtype : Tregistertype;
|
||||
{ default subregister used }
|
||||
defaultsub : tsubregister;
|
||||
{# Adds an interference edge.}
|
||||
procedure add_edge(u,v:Tsuperregister);
|
||||
procedure add_constraints(reg:Tregister);virtual;
|
||||
private
|
||||
{# First imaginary register.}
|
||||
first_imaginary : Tsuperregister;
|
||||
{# Highest register allocated until now.}
|
||||
@ -259,7 +228,21 @@ unit rgobj;
|
||||
coalesced_moves,
|
||||
constrained_moves : Tlinkedlist;
|
||||
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 ungetregisterinline(list:Taasmoutput;position:Tai;r:Tregister);
|
||||
procedure add_edges_used(u:Tsuperregister);
|
||||
@ -429,7 +412,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function trgobj.getnewreg:tsuperregister;
|
||||
function trgobj.getnewreg(subreg:tsubregister):tsuperregister;
|
||||
var
|
||||
oldmaxreginfo : tsuperregister;
|
||||
begin
|
||||
@ -447,24 +430,16 @@ implementation
|
||||
{ Do we really need it to clear it ? At least for 1.0.x (PFV) }
|
||||
fillchar(reginfo[oldmaxreginfo],(maxreginfo-oldmaxreginfo)*sizeof(treginfo),0);
|
||||
end;
|
||||
reginfo[result].subreg:=subreg;
|
||||
end;
|
||||
|
||||
|
||||
function trgobj.getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;
|
||||
var
|
||||
p : Tsuperregister;
|
||||
r : Tregister;
|
||||
begin
|
||||
p:=getnewreg;
|
||||
live_registers.add(p);
|
||||
if defaultsub=R_SUBNONE then
|
||||
r:=newreg(regtype,p,R_SUBNONE)
|
||||
result:=newreg(regtype,getnewreg(R_SUBNONE),R_SUBNONE)
|
||||
else
|
||||
r:=newreg(regtype,p,subreg);
|
||||
list.concat(Tai_regalloc.alloc(r));
|
||||
add_edges_used(p);
|
||||
add_constraints(r);
|
||||
result:=r;
|
||||
result:=newreg(regtype,getnewreg(subreg),subreg);
|
||||
end;
|
||||
|
||||
|
||||
@ -475,29 +450,23 @@ implementation
|
||||
|
||||
|
||||
procedure trgobj.ungetregister(list:Taasmoutput;r:Tregister);
|
||||
|
||||
var supreg:Tsuperregister;
|
||||
|
||||
begin
|
||||
supreg:=getsupreg(r);
|
||||
if live_registers.delete(supreg) then
|
||||
list.concat(Tai_regalloc.dealloc(r));
|
||||
end;
|
||||
begin
|
||||
{ Only explicit allocs insert regalloc info }
|
||||
if getsupreg(r)<first_imaginary then
|
||||
list.concat(Tai_regalloc.dealloc(r));
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.getexplicitregister(list:Taasmoutput;r:Tregister);
|
||||
|
||||
var supreg:Tsuperregister;
|
||||
|
||||
begin
|
||||
supreg:=getsupreg(r);
|
||||
live_registers.add(supreg);
|
||||
if supreg<first_imaginary then
|
||||
var
|
||||
supreg:Tsuperregister;
|
||||
begin
|
||||
supreg:=getsupreg(r);
|
||||
if supreg>=first_imaginary then
|
||||
internalerror(2003121503);
|
||||
include(used_in_proc,supreg);
|
||||
list.concat(Tai_regalloc.alloc(r));
|
||||
add_edges_used(supreg);
|
||||
add_constraints(r);
|
||||
end;
|
||||
list.concat(Tai_regalloc.alloc(r));
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);
|
||||
@ -507,7 +476,7 @@ implementation
|
||||
begin
|
||||
for i:=0 to first_imaginary-1 do
|
||||
if i in r then
|
||||
getexplicitregister(list,i);
|
||||
getexplicitregister(list,newreg(regtype,i,defaultsub));
|
||||
end;
|
||||
|
||||
|
||||
@ -518,7 +487,7 @@ implementation
|
||||
begin
|
||||
for i:=0 to first_imaginary-1 do
|
||||
if i in r then
|
||||
ungetregister(list,i);
|
||||
ungetregister(list,newreg(regtype,i,defaultsub));
|
||||
end;
|
||||
|
||||
|
||||
@ -527,6 +496,12 @@ implementation
|
||||
spillingcounter:byte;
|
||||
endspill:boolean;
|
||||
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.}
|
||||
spillingcounter:=0;
|
||||
repeat
|
||||
@ -542,6 +517,7 @@ implementation
|
||||
endspill:=not spill_registers(list,headertai);
|
||||
end;
|
||||
until endspill;
|
||||
translate_registers(list);
|
||||
end;
|
||||
|
||||
|
||||
@ -588,8 +564,9 @@ implementation
|
||||
var i:word;
|
||||
|
||||
begin
|
||||
for i:=0 to live_registers.length-1 do
|
||||
add_edge(u,live_registers.buf[i]);
|
||||
if live_registers.length>0 then
|
||||
for i:=0 to live_registers.length-1 do
|
||||
add_edge(u,live_registers.buf[i]);
|
||||
end;
|
||||
|
||||
{$ifdef EXTDEBUG}
|
||||
@ -644,6 +621,21 @@ implementation
|
||||
inc(reginfo[u].movelist^.count);
|
||||
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);
|
||||
|
||||
{This procedure notifies a certain as a move instruction so the
|
||||
@ -827,8 +819,8 @@ implementation
|
||||
procedure trgobj.simplify;
|
||||
|
||||
var adj : Psuperregisterworklist;
|
||||
p,n : Tsuperregister;
|
||||
min,i:word;
|
||||
n : Tsuperregister;
|
||||
i : word;
|
||||
begin
|
||||
{We take the element with the least interferences out of the
|
||||
simplifyworklist. Since the simplifyworklist is now sorted, we
|
||||
@ -1367,7 +1359,7 @@ implementation
|
||||
var p:Tsuperregister;
|
||||
r:Tregister;
|
||||
begin
|
||||
p:=getnewreg;
|
||||
p:=getnewreg(subreg);
|
||||
live_registers.add(p);
|
||||
r:=newreg(regtype,p,subreg);
|
||||
if position=nil then
|
||||
@ -1395,6 +1387,105 @@ implementation
|
||||
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;
|
||||
|
||||
{Returns true if any help registers have been used.}
|
||||
@ -1473,8 +1564,7 @@ implementation
|
||||
live_registers,
|
||||
spill_temps^) then
|
||||
spill_registers:=true;
|
||||
|
||||
if Taicpu_abstract(p).is_move then
|
||||
if Taicpu_abstract(p).is_reg_move then
|
||||
add_move_instruction(Taicpu(p));
|
||||
end;
|
||||
end;
|
||||
@ -1579,15 +1669,16 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure Trgobj.check_unreleasedregs;
|
||||
begin
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
{
|
||||
$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
|
||||
|
||||
Revision 1.101 2003/12/15 15:58:58 peter
|
||||
|
@ -13,6 +13,7 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
{$mode objfpc}
|
||||
{$i+}
|
||||
program mkx86reg;
|
||||
|
||||
@ -383,8 +384,8 @@ begin
|
||||
end
|
||||
else
|
||||
first:=false;
|
||||
writeln(confile,names[i],' = ',numbers[i],';');
|
||||
write(numfile,numbers[i]);
|
||||
writeln(confile,names[i],' = ','tregister(',numbers[i],')',';');
|
||||
write(numfile,'tregister(',numbers[i],')');
|
||||
write(stdfile,'''',stdnames[i],'''');
|
||||
write(attfile,'''',attnames[i],'''');
|
||||
if not(x86_64) then
|
||||
@ -457,7 +458,13 @@ begin
|
||||
end.
|
||||
{
|
||||
$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
|
||||
|
||||
Revision 1.2 2003/09/03 15:55:02 peter
|
||||
|
@ -201,7 +201,7 @@ interface
|
||||
procedure Pass2(sec:TAsmObjectdata);virtual;
|
||||
procedure SetOperandOrder(order:TOperandOrder);
|
||||
function is_nop:boolean;override;
|
||||
function is_move:boolean;override;
|
||||
function is_reg_move:boolean;override;
|
||||
function spill_registers(list:Taasmoutput;
|
||||
rgget:Trggetproc;
|
||||
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);
|
||||
end;
|
||||
|
||||
function Taicpu.is_move:boolean;
|
||||
function Taicpu.is_reg_move:boolean;
|
||||
|
||||
begin
|
||||
{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
|
||||
interrest to the register allocation, therefore we only return true
|
||||
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));
|
||||
end;
|
||||
|
||||
@ -2344,7 +2344,13 @@ implementation
|
||||
end.
|
||||
{
|
||||
$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
|
||||
- Worklist no longer a ringbuffer
|
||||
- No find operations are left
|
||||
|
@ -43,10 +43,10 @@ unit cgx86;
|
||||
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||
procedure getexplicitregister(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 deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
|
||||
function uses_registers(rt:Tregistertype):boolean;override;
|
||||
procedure add_reg_instruction(instr:Tai;r:tregister);override;
|
||||
procedure dec_fpu_stack;
|
||||
procedure inc_fpu_stack;
|
||||
|
||||
@ -211,15 +211,6 @@ unit cgx86;
|
||||
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);
|
||||
begin
|
||||
if rt<>R_FPUREGISTER then
|
||||
@ -243,6 +234,13 @@ unit cgx86;
|
||||
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;
|
||||
begin
|
||||
dec(rgfpu.fpuvaroffset);
|
||||
@ -1426,18 +1424,18 @@ unit cgx86;
|
||||
system_i386_win32,
|
||||
{$endif}
|
||||
system_i386_freebsd,
|
||||
system_i386_netbsd,
|
||||
// system_i386_openbsd,
|
||||
system_i386_netbsd,
|
||||
// system_i386_openbsd,
|
||||
system_i386_wdosx,
|
||||
system_i386_linux:
|
||||
begin
|
||||
Case target_info.system Of
|
||||
system_i386_freebsd : mcountprefix:='.';
|
||||
system_i386_netbsd : mcountprefix:='__';
|
||||
// system_i386_openbsd : mcountprefix:='.';
|
||||
else
|
||||
mcountPrefix:='';
|
||||
end;
|
||||
Case target_info.system Of
|
||||
system_i386_freebsd : mcountprefix:='.';
|
||||
system_i386_netbsd : mcountprefix:='__';
|
||||
// system_i386_openbsd : mcountprefix:='.';
|
||||
else
|
||||
mcountPrefix:='';
|
||||
end;
|
||||
objectlibrary.getaddrlabel(pl);
|
||||
list.concat(Tai_section.Create(sec_data));
|
||||
list.concat(Tai_align.Create(4));
|
||||
@ -1684,7 +1682,13 @@ unit cgx86;
|
||||
end.
|
||||
{
|
||||
$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
|
||||
|
||||
Revision 1.89 2003/12/06 01:15:23 florian
|
||||
|
@ -176,7 +176,7 @@ uses
|
||||
{$endif x86_64}
|
||||
);
|
||||
|
||||
regstabs_table : array[tregisterindex] of tregister = (
|
||||
regstabs_table : array[tregisterindex] of shortint = (
|
||||
{$ifdef x86_64}
|
||||
{$i r8664stab.inc}
|
||||
{$else x86_64}
|
||||
@ -526,7 +526,13 @@ implementation
|
||||
end.
|
||||
{
|
||||
$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
|
||||
|
||||
Revision 1.29 2003/10/30 17:13:18 peter
|
||||
|
Loading…
Reference in New Issue
Block a user