mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-17 13:39:36 +02:00
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
* tregisteralloctor renamed to trgobj * removed rgobj from a lot of units * moved location_* and reference_* to cgobj * first things for mmx register allocation
This commit is contained in:
parent
8f92b2f14e
commit
fb81b7ebbb
@ -498,7 +498,7 @@ interface
|
||||
taasmoutput = class(tlinkedlist)
|
||||
constructor create;
|
||||
function getlasttaifilepos : pfileposinfo;
|
||||
procedure translate_registers(const table:Ttranstable);
|
||||
procedure translate_registers(regtype:tregistertype;const table:Ttranstable);
|
||||
end;
|
||||
|
||||
|
||||
@ -2090,7 +2090,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Taasmoutput.translate_registers(const table:Ttranstable);
|
||||
procedure Taasmoutput.translate_registers(regtype:tregistertype;const table:Ttranstable);
|
||||
|
||||
var p,q:Tai;
|
||||
i:shortint;
|
||||
@ -2106,22 +2106,25 @@ implementation
|
||||
begin
|
||||
case p.typ of
|
||||
ait_regalloc:
|
||||
if (getregtype(Tai_regalloc(p).reg)=R_INTREGISTER) then
|
||||
if (getregtype(Tai_regalloc(p).reg)=regtype) then
|
||||
setsupreg(Tai_regalloc(p).reg,table[getsupreg(Tai_regalloc(p).reg)]);
|
||||
ait_instruction:
|
||||
begin
|
||||
for i:=0 to Taicpu_abstract(p).ops-1 do
|
||||
case Taicpu_abstract(p).oper[i].typ of
|
||||
Top_reg:
|
||||
if (getregtype(Taicpu_abstract(p).oper[i].reg)=R_INTREGISTER) then
|
||||
if (getregtype(Taicpu_abstract(p).oper[i].reg)=regtype) then
|
||||
setsupreg(Taicpu_abstract(p).oper[i].reg,table[getsupreg(Taicpu_abstract(p).oper[i].reg)]);
|
||||
Top_ref:
|
||||
begin
|
||||
r:=Taicpu_abstract(p).oper[i].ref;
|
||||
if r^.base<>NR_NO then
|
||||
setsupreg(r^.base,table[getsupreg(r^.base)]);
|
||||
if r^.index<>NR_NO then
|
||||
setsupreg(r^.index,table[getsupreg(r^.index)]);
|
||||
if regtype=R_INTREGISTER then
|
||||
begin
|
||||
r:=Taicpu_abstract(p).oper[i].ref;
|
||||
if r^.base<>NR_NO then
|
||||
setsupreg(r^.base,table[getsupreg(r^.base)]);
|
||||
if r^.index<>NR_NO then
|
||||
setsupreg(r^.index,table[getsupreg(r^.index)]);
|
||||
end;
|
||||
end;
|
||||
{$ifdef arm}
|
||||
Top_shifterop:
|
||||
@ -2151,7 +2154,14 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.41 2003-10-01 20:34:48 peter
|
||||
Revision 1.42 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.41 2003/10/01 20:34:48 peter
|
||||
* procinfo unit contains tprocinfo
|
||||
* cginfo renamed to cgbase
|
||||
* moved cgmessage to verbose
|
||||
|
@ -93,9 +93,9 @@ unit cg64f32;
|
||||
implementation
|
||||
|
||||
uses
|
||||
globtype,globals,systems,
|
||||
globals,systems,
|
||||
verbose,
|
||||
symbase,symconst,symdef,defutil,rgobj,tgobj,paramgr;
|
||||
symbase,symconst,symdef,defutil,tgobj,paramgr;
|
||||
|
||||
{****************************************************************************
|
||||
Helpers
|
||||
@ -761,7 +761,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.51 2003-10-09 21:31:37 daniel
|
||||
Revision 1.52 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.51 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.50 2003/10/01 20:34:48 peter
|
||||
|
@ -75,6 +75,8 @@ unit cgobj;
|
||||
{# Gets a register suitable to do integer operations on.}
|
||||
function getaddressregister(list:Taasmoutput):Tregister;virtual;abstract;
|
||||
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract;
|
||||
function getmmxregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract;
|
||||
function getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract;
|
||||
function getabtregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract;
|
||||
{Does the generic cg need SIMD registers, like getmmxregister? Or should
|
||||
the cpu specific child cg object have such a method?}
|
||||
@ -492,6 +494,31 @@ unit cgobj;
|
||||
procedure g_rangecheck64(list: taasmoutput; const l:tlocation; fromdef,todef: tdef);virtual;abstract;
|
||||
end;
|
||||
|
||||
|
||||
{ trerefence handling }
|
||||
|
||||
{# Clear to zero a treference }
|
||||
procedure reference_reset(var ref : treference);
|
||||
{# Clear to zero a treference, and set is base address
|
||||
to base register.
|
||||
}
|
||||
procedure reference_reset_base(var ref : treference;base : tregister;offset : longint);
|
||||
procedure reference_reset_symbol(var ref : treference;sym : tasmsymbol;offset : longint);
|
||||
procedure reference_release(list: taasmoutput; const ref : treference);
|
||||
{ This routine verifies if two references are the same, and
|
||||
if so, returns TRUE, otherwise returns false.
|
||||
}
|
||||
function references_equal(sref : treference;dref : treference) : boolean;
|
||||
|
||||
{ tlocation handling }
|
||||
|
||||
procedure location_reset(var l : tlocation;lt:TCGLoc;lsize:TCGSize);
|
||||
procedure location_release(list: taasmoutput; const l : tlocation);
|
||||
procedure location_freetemp(list: taasmoutput; const l : tlocation);
|
||||
procedure location_copy(var destloc:tlocation; const sourceloc : tlocation);
|
||||
procedure location_swap(var destloc,sourceloc : tlocation);
|
||||
|
||||
|
||||
var
|
||||
{# Main code generator class }
|
||||
cg : tcg;
|
||||
@ -503,8 +530,8 @@ implementation
|
||||
|
||||
uses
|
||||
globals,globtype,options,systems,
|
||||
verbose,defutil,paramgr,symsym,
|
||||
rgobj,cutils;
|
||||
verbose,defutil,paramgr,
|
||||
tgobj,cutils;
|
||||
|
||||
const
|
||||
{ Please leave this here, this module should NOT use
|
||||
@ -1542,6 +1569,10 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
TCG64
|
||||
*****************************************************************************}
|
||||
|
||||
procedure tcg64.a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : qword; regsrc,regdst : tregister64);
|
||||
begin
|
||||
a_load64_reg_reg(list,regsrc,regdst,false);
|
||||
@ -1555,6 +1586,103 @@ implementation
|
||||
a_op64_reg_reg(list,op,regsrc1,regdst);
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
TReference
|
||||
****************************************************************************}
|
||||
|
||||
procedure reference_reset(var ref : treference);
|
||||
begin
|
||||
FillChar(ref,sizeof(treference),0);
|
||||
{$ifdef arm}
|
||||
ref.signindex:=1;
|
||||
{$endif arm}
|
||||
end;
|
||||
|
||||
|
||||
procedure reference_reset_base(var ref : treference;base : tregister;offset : longint);
|
||||
begin
|
||||
reference_reset(ref);
|
||||
ref.base:=base;
|
||||
ref.offset:=offset;
|
||||
end;
|
||||
|
||||
|
||||
procedure reference_reset_symbol(var ref : treference;sym : tasmsymbol;offset : longint);
|
||||
begin
|
||||
reference_reset(ref);
|
||||
ref.symbol:=sym;
|
||||
ref.offset:=offset;
|
||||
end;
|
||||
|
||||
|
||||
procedure reference_release(list: taasmoutput; const ref : treference);
|
||||
begin
|
||||
cg.ungetreference(list,ref);
|
||||
end;
|
||||
|
||||
|
||||
function references_equal(sref : treference;dref : treference):boolean;
|
||||
begin
|
||||
references_equal:=CompareByte(sref,dref,sizeof(treference))=0;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TLocation
|
||||
****************************************************************************}
|
||||
|
||||
procedure location_reset(var l : tlocation;lt:TCGLoc;lsize:TCGSize);
|
||||
begin
|
||||
FillChar(l,sizeof(tlocation),0);
|
||||
l.loc:=lt;
|
||||
l.size:=lsize;
|
||||
{$ifdef arm}
|
||||
if l.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||
l.reference.signindex:=1;
|
||||
{$endif arm}
|
||||
end;
|
||||
|
||||
|
||||
procedure location_release(list: taasmoutput; const l : tlocation);
|
||||
begin
|
||||
case l.loc of
|
||||
LOC_REGISTER,LOC_CREGISTER :
|
||||
begin
|
||||
cg.ungetregister(list,l.register);
|
||||
if l.size in [OS_64,OS_S64] then
|
||||
cg.ungetregister(list,l.registerhigh);
|
||||
end;
|
||||
LOC_FPUREGISTER,LOC_CFPUREGISTER :
|
||||
cg.ungetregister(list,l.register);
|
||||
LOC_CREFERENCE,LOC_REFERENCE :
|
||||
cg.ungetreference(list, l.reference);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure location_freetemp(list:taasmoutput; const l : tlocation);
|
||||
begin
|
||||
if (l.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
||||
tg.ungetiftemp(list,l.reference);
|
||||
end;
|
||||
|
||||
|
||||
procedure location_copy(var destloc:tlocation; const sourceloc : tlocation);
|
||||
begin
|
||||
destloc:=sourceloc;
|
||||
end;
|
||||
|
||||
|
||||
procedure location_swap(var destloc,sourceloc : tlocation);
|
||||
var
|
||||
swapl : tlocation;
|
||||
begin
|
||||
swapl := destloc;
|
||||
destloc := sourceloc;
|
||||
sourceloc := swapl;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
initialization
|
||||
;
|
||||
@ -1564,7 +1692,14 @@ finalization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.127 2003-10-09 21:31:37 daniel
|
||||
Revision 1.128 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.127 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.126 2003/10/01 20:34:48 peter
|
||||
|
@ -29,7 +29,7 @@ interface
|
||||
uses
|
||||
cclasses,
|
||||
cpuinfo,
|
||||
globals,
|
||||
globtype,globals,tokens,
|
||||
node,
|
||||
symconst,symbase,symtype,symdef;
|
||||
|
||||
@ -114,9 +114,8 @@ interface
|
||||
implementation
|
||||
|
||||
uses
|
||||
globtype,tokens,
|
||||
verbose,systems,
|
||||
symsym,symtable,
|
||||
symtable,symsym,
|
||||
defutil,symutil;
|
||||
|
||||
|
||||
@ -1216,7 +1215,14 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.31 2003-10-07 21:14:32 peter
|
||||
Revision 1.32 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.31 2003/10/07 21:14:32 peter
|
||||
* compare_paras() has a parameter to ignore hidden parameters
|
||||
* cross unit overload searching ignores hidden parameters when
|
||||
comparing parameter lists. Now function(string):string is
|
||||
|
@ -57,7 +57,7 @@ unit cgcpu;
|
||||
uses
|
||||
globtype,globals,verbose,systems,cutils,
|
||||
symdef,symsym,defutil,paramgr,
|
||||
rgobj,tgobj;
|
||||
tgobj;
|
||||
|
||||
|
||||
class function tcg386.reg_cgsize(const reg: tregister): tcgsize;
|
||||
@ -207,7 +207,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.39 2003-10-01 20:34:49 peter
|
||||
Revision 1.40 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.39 2003/10/01 20:34:49 peter
|
||||
* procinfo unit contains tprocinfo
|
||||
* cginfo renamed to cgbase
|
||||
* moved cgmessage to verbose
|
||||
|
@ -47,6 +47,7 @@ unit cpupara;
|
||||
function get_para_align(calloption : tproccalloption):byte;override;
|
||||
function get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;override;
|
||||
function get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset;override;
|
||||
function get_volatile_registers_mmx(calloption : tproccalloption):tsuperregisterset;override;
|
||||
function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override;
|
||||
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tlinkedlist):longint;override;
|
||||
@ -60,8 +61,7 @@ unit cpupara;
|
||||
|
||||
uses
|
||||
cutils,
|
||||
systems,globals,verbose,
|
||||
symsym,
|
||||
systems,verbose,
|
||||
defutil,
|
||||
cpuinfo;
|
||||
|
||||
@ -188,7 +188,13 @@ unit cpupara;
|
||||
|
||||
function ti386paramanager.get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset;
|
||||
begin
|
||||
result:=[first_fpu_supreg..last_fpu_supreg];;
|
||||
result:=[first_fpu_supreg..last_fpu_supreg];
|
||||
end;
|
||||
|
||||
|
||||
function ti386paramanager.get_volatile_registers_mmx(calloption : tproccalloption):tsuperregisterset;
|
||||
begin
|
||||
result:=[first_mmx_supreg..last_mmx_supreg];
|
||||
end;
|
||||
|
||||
|
||||
@ -440,7 +446,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.38 2003-10-07 15:17:07 peter
|
||||
Revision 1.39 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.38 2003/10/07 15:17:07 peter
|
||||
* inline supported again, LOC_REFERENCEs are used to pass the
|
||||
parameters
|
||||
* inlineparasymtable,inlinelocalsymtable removed
|
||||
|
@ -61,7 +61,7 @@ interface
|
||||
aasmbase,aasmtai,aasmcpu,defutil,htypechk,
|
||||
cgbase,pass_2,regvars,
|
||||
ncon,nset,
|
||||
cga,cgx86,ncgutil,tgobj,rgobj,cgobj,cg64f32,rgcpu;
|
||||
cga,cgx86,ncgutil,cgobj,cg64f32;
|
||||
|
||||
{*****************************************************************************
|
||||
Helpers
|
||||
@ -550,7 +550,6 @@ interface
|
||||
resflags : tresflags;
|
||||
pushedfpu,
|
||||
cmpop : boolean;
|
||||
r : Tregister;
|
||||
begin
|
||||
pass_left_and_right(pushedfpu);
|
||||
|
||||
@ -1083,9 +1082,9 @@ interface
|
||||
pushedfpu,
|
||||
cmpop : boolean;
|
||||
mmxbase : tmmxtype;
|
||||
r,hregister : tregister;
|
||||
hreg,
|
||||
hregister : tregister;
|
||||
begin
|
||||
(*
|
||||
pass_left_and_right(pushedfpu);
|
||||
|
||||
cmpop:=false;
|
||||
@ -1178,7 +1177,7 @@ interface
|
||||
{ register variable ? }
|
||||
if (left.location.loc=LOC_CMMXREGISTER) then
|
||||
begin
|
||||
hregister:=rg.getregistermm(exprasmlist);
|
||||
hregister:=cg.getmmxregister(exprasmlist,OS_M64);
|
||||
emit_reg_reg(A_MOVQ,S_NO,left.location.register,hregister);
|
||||
end
|
||||
else
|
||||
@ -1188,7 +1187,7 @@ interface
|
||||
|
||||
location_release(exprasmlist,left.location);
|
||||
|
||||
hregister:=rg.getregistermm(exprasmlist);
|
||||
hregister:=cg.getmmxregister(exprasmlist,OS_M64);
|
||||
emit_ref_reg(A_MOVQ,S_NO,left.location.reference,hregister);
|
||||
end;
|
||||
|
||||
@ -1204,18 +1203,22 @@ interface
|
||||
begin
|
||||
if right.location.loc=LOC_CMMXREGISTER then
|
||||
begin
|
||||
emit_reg_reg(A_MOVQ,S_NO,right.location.register,NR_MM7);
|
||||
emit_reg_reg(op,S_NO,left.location.register,NR_MM7);
|
||||
emit_reg_reg(A_MOVQ,S_NO,NR_MM7,left.location.register);
|
||||
hreg:=cg.getmmxregister(exprasmlist,OS_M64);
|
||||
emit_reg_reg(A_MOVQ,S_NO,right.location.register,hreg);
|
||||
emit_reg_reg(op,S_NO,left.location.register,hreg);
|
||||
cg.ungetregister(exprasmlist,hreg);
|
||||
emit_reg_reg(A_MOVQ,S_NO,hreg,left.location.register);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
||||
internalerror(200203247);
|
||||
emit_ref_reg(A_MOVQ,S_NO,right.location.reference,NR_MM7);
|
||||
emit_reg_reg(op,S_NO,left.location.register,NR_MM7);
|
||||
emit_reg_reg(A_MOVQ,S_NO,NR_MM7,left.location.register);
|
||||
location_release(exprasmlist,right.location);
|
||||
hreg:=cg.getmmxregister(exprasmlist,OS_M64);
|
||||
emit_ref_reg(A_MOVQ,S_NO,right.location.reference,hreg);
|
||||
emit_reg_reg(op,S_NO,left.location.register,hreg);
|
||||
cg.ungetregister(exprasmlist,hreg);
|
||||
emit_reg_reg(A_MOVQ,S_NO,hreg,left.location.register);
|
||||
end;
|
||||
end
|
||||
else
|
||||
@ -1254,7 +1257,6 @@ interface
|
||||
location_release(exprasmlist,left.location);
|
||||
end;
|
||||
set_result_location(cmpop,true);
|
||||
*)
|
||||
end;
|
||||
{$endif SUPPORT_MMX}
|
||||
|
||||
@ -1492,7 +1494,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.82 2003-10-09 21:31:37 daniel
|
||||
Revision 1.83 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.82 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.81 2003/10/08 09:13:16 florian
|
||||
|
@ -45,20 +45,14 @@ implementation
|
||||
uses
|
||||
globtype,systems,
|
||||
cutils,verbose,globals,
|
||||
symconst,symbase,symdef,symsym,symtable,defutil,
|
||||
{$ifdef GDB}
|
||||
{$ifdef delphi}
|
||||
sysutils,
|
||||
{$else}
|
||||
strings,
|
||||
{$endif}
|
||||
gdb,
|
||||
{$endif GDB}
|
||||
cgbase,pass_2,
|
||||
cpubase,paramgr,procinfo,
|
||||
aasmbase,aasmtai,aasmcpu,
|
||||
node,ncal,nbas,nmem,nld,ncnv,
|
||||
ncgutil,cga,cgobj,tgobj,rgobj,cpuinfo;
|
||||
cgbase,
|
||||
cpubase,paramgr,
|
||||
aasmtai,aasmcpu,
|
||||
ncal,nbas,nmem,nld,ncnv,
|
||||
cga,cgobj,cpuinfo;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
@ -170,7 +164,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.97 2003-10-09 21:31:37 daniel
|
||||
Revision 1.98 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.97 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.96 2003/10/01 20:34:49 peter
|
||||
|
@ -62,12 +62,12 @@ interface
|
||||
implementation
|
||||
|
||||
uses
|
||||
verbose,systems,globtype,
|
||||
verbose,systems,
|
||||
symconst,symdef,aasmbase,aasmtai,aasmcpu,
|
||||
cgbase,pass_2,
|
||||
cgbase,
|
||||
ncon,ncal,ncnv,
|
||||
cpubase,
|
||||
cgobj,cga,cgx86,tgobj,rgobj,rgcpu,ncgutil;
|
||||
cgobj,cga,cgx86;
|
||||
|
||||
|
||||
function ti386typeconvnode.first_int_to_real : tnode;
|
||||
@ -332,7 +332,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.66 2003-10-09 21:31:37 daniel
|
||||
Revision 1.67 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.66 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.65 2003/10/01 20:34:49 peter
|
||||
|
@ -38,10 +38,10 @@ interface
|
||||
implementation
|
||||
|
||||
uses
|
||||
systems,globtype,globals,
|
||||
systems,globals,
|
||||
defutil,
|
||||
cpubase,
|
||||
cga,cgx86,cgobj,cgbase,rgobj,rgcpu;
|
||||
cga,cgx86,cgobj,cgbase;
|
||||
|
||||
{*****************************************************************************
|
||||
TI386REALCONSTNODE
|
||||
@ -91,7 +91,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.23 2003-10-09 21:31:37 daniel
|
||||
Revision 1.24 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.23 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.22 2003/10/01 20:34:49 peter
|
||||
|
@ -60,14 +60,14 @@ interface
|
||||
implementation
|
||||
|
||||
uses
|
||||
systems,globtype,
|
||||
systems,
|
||||
cutils,verbose,
|
||||
defutil,
|
||||
aasmtai,
|
||||
cgbase,pass_2,
|
||||
cpubase,paramgr,
|
||||
nbas,ncon,ncal,ncnv,nld,
|
||||
cga,cgx86,tgobj,ncgutil,cgobj,rgobj,rgcpu;
|
||||
cga,cgx86,cgobj;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
@ -324,7 +324,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.69 2003-10-09 21:31:37 daniel
|
||||
Revision 1.70 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.69 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.68 2003/10/01 20:34:49 peter
|
||||
|
@ -65,7 +65,7 @@ implementation
|
||||
cgbase,pass_1,pass_2,
|
||||
ncon,
|
||||
cpubase,cpuinfo,
|
||||
cga,tgobj,ncgutil,cgobj,rgobj;
|
||||
cga,ncgutil,cgobj;
|
||||
|
||||
{*****************************************************************************
|
||||
TI386MODDIVNODE
|
||||
@ -387,28 +387,27 @@ implementation
|
||||
procedure ti386unaryminusnode.second_mmx;
|
||||
var
|
||||
op : tasmop;
|
||||
hreg : tregister;
|
||||
begin
|
||||
(*
|
||||
secondpass(left);
|
||||
location_reset(location,LOC_MMXREGISTER,OS_NO);
|
||||
hreg:=cg.getmmxregister(exprasmlist,OS_M64);
|
||||
emit_reg_reg(A_PXOR,S_NO,hreg,hreg);
|
||||
case left.location.loc of
|
||||
LOC_MMXREGISTER:
|
||||
begin
|
||||
location.register:=left.location.register;
|
||||
emit_reg_reg(A_PXOR,S_NO,NR_MM7,NR_MM7);
|
||||
end;
|
||||
LOC_CMMXREGISTER:
|
||||
begin
|
||||
location.register:=rg.getregistermm(exprasmlist);
|
||||
emit_reg_reg(A_PXOR,S_NO,NR_MM7,NR_MM7);
|
||||
location.register:=cg.getmmxregister(exprasmlist,OS_M64);
|
||||
emit_reg_reg(A_MOVQ,S_NO,left.location.register,location.register);
|
||||
end;
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE:
|
||||
begin
|
||||
reference_release(exprasmlist,left.location.reference);
|
||||
location.register:=rg.getregistermm(exprasmlist);
|
||||
emit_reg_reg(A_PXOR,S_NO,NR_MM7,NR_MM7);
|
||||
location.register:=cg.getmmxregister(exprasmlist,OS_M64);
|
||||
emit_ref_reg(A_MOVQ,S_NO,left.location.reference,location.register);
|
||||
end;
|
||||
else
|
||||
@ -434,9 +433,9 @@ implementation
|
||||
mmxs32bit,mmxu32bit:
|
||||
op:=A_PSUBD;
|
||||
end;
|
||||
emit_reg_reg(op,S_NO,location.register,NR_MM7);
|
||||
emit_reg_reg(A_MOVQ,S_NO,NR_MM7,location.register);
|
||||
*)
|
||||
emit_reg_reg(op,S_NO,location.register,hreg);
|
||||
cg.ungetregister(exprasmlist,hreg);
|
||||
emit_reg_reg(A_MOVQ,S_NO,hreg,location.register);
|
||||
end;
|
||||
{$endif SUPPORT_MMX}
|
||||
|
||||
@ -527,10 +526,9 @@ implementation
|
||||
{$ifdef SUPPORT_MMX}
|
||||
procedure ti386notnode.second_mmx;
|
||||
|
||||
var r:Tregister;
|
||||
var hreg,r:Tregister;
|
||||
|
||||
begin
|
||||
(*
|
||||
secondpass(left);
|
||||
location_reset(location,LOC_MMXREGISTER,OS_NO);
|
||||
r:=cg.getintregister(exprasmlist,OS_INT);
|
||||
@ -541,27 +539,28 @@ implementation
|
||||
location_copy(location,left.location);
|
||||
LOC_CMMXREGISTER:
|
||||
begin
|
||||
location.register:=rg.getregistermm(exprasmlist);
|
||||
location.register:=cg.getmmxregister(exprasmlist,OS_M64);
|
||||
emit_reg_reg(A_MOVQ,S_NO,left.location.register,location.register);
|
||||
end;
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE:
|
||||
begin
|
||||
location_release(exprasmlist,left.location);
|
||||
location.register:=rg.getregistermm(exprasmlist);
|
||||
location.register:=cg.getmmxregister(exprasmlist,OS_M64);
|
||||
emit_ref_reg(A_MOVQ,S_NO,left.location.reference,location.register);
|
||||
end;
|
||||
end;
|
||||
{ load mask }
|
||||
emit_reg_reg(A_MOVD,S_NO,r,NR_MM7);
|
||||
rg.ungetregisterint(exprasmlist,r);
|
||||
hreg:=cg.getmmxregister(exprasmlist,OS_M64);
|
||||
emit_reg_reg(A_MOVD,S_NO,r,hreg);
|
||||
cg.ungetregister(exprasmlist,r);
|
||||
{ lower 32 bit }
|
||||
emit_reg_reg(A_PXOR,S_D,NR_MM7,location.register);
|
||||
emit_reg_reg(A_PXOR,S_D,hreg,location.register);
|
||||
{ shift mask }
|
||||
emit_const_reg(A_PSLLQ,S_NO,32,NR_MM7);
|
||||
emit_const_reg(A_PSLLQ,S_NO,32,hreg);
|
||||
{ higher 32 bit }
|
||||
emit_reg_reg(A_PXOR,S_D,NR_MM7,location.register);
|
||||
*)
|
||||
cg.ungetregister(exprasmlist,hreg);
|
||||
emit_reg_reg(A_PXOR,S_D,hreg,location.register);
|
||||
end;
|
||||
{$endif SUPPORT_MMX}
|
||||
|
||||
@ -573,7 +572,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.64 2003-10-09 21:31:37 daniel
|
||||
Revision 1.65 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.64 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.63 2003/10/01 20:34:49 peter
|
||||
|
@ -55,7 +55,7 @@ implementation
|
||||
symdef,paramgr,
|
||||
aasmtai,
|
||||
nld,ncon,nadd,
|
||||
cgobj,tgobj,rgobj;
|
||||
cgobj;
|
||||
|
||||
{*****************************************************************************
|
||||
TI386ADDRNODE
|
||||
@ -142,7 +142,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.57 2003-10-09 21:31:37 daniel
|
||||
Revision 1.58 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.57 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.56 2003/10/01 20:34:49 peter
|
||||
|
@ -33,11 +33,11 @@ uses
|
||||
systems,
|
||||
verbose,globals,globtype,
|
||||
aasmbase,aasmtai,
|
||||
symconst,symtype,symdef,symsym,
|
||||
symconst,symdef,
|
||||
fmodule,
|
||||
nobj,
|
||||
cpuinfo,cpubase,
|
||||
cga,tgobj,rgobj,cgobj;
|
||||
cga,cgobj;
|
||||
|
||||
type
|
||||
ti386classheader=class(tclassheader)
|
||||
@ -223,7 +223,14 @@ initialization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.26 2003-10-01 20:34:49 peter
|
||||
Revision 1.27 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.26 2003/10/01 20:34:49 peter
|
||||
* procinfo unit contains tprocinfo
|
||||
* cginfo renamed to cgbase
|
||||
* moved cgmessage to verbose
|
||||
|
@ -54,7 +54,7 @@ implementation
|
||||
cgbase,pass_2,
|
||||
ncon,
|
||||
cpubase,cpuinfo,procinfo,
|
||||
cga,cgobj,tgobj,ncgutil,rgobj,
|
||||
cga,cgobj,ncgutil,
|
||||
cgx86;
|
||||
|
||||
|
||||
@ -672,7 +672,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.68 2003-10-09 21:31:37 daniel
|
||||
Revision 1.69 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.68 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.67 2003/10/01 20:34:49 peter
|
||||
|
@ -51,7 +51,7 @@ Implementation
|
||||
{ register allocator }
|
||||
rautils,rax86,itx86int,
|
||||
{ codegen }
|
||||
rgobj,cgbase,cgobj,procinfo
|
||||
cgbase,cgobj,procinfo
|
||||
;
|
||||
|
||||
type
|
||||
@ -1932,7 +1932,14 @@ finalization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.55 2003-10-07 18:21:18 peter
|
||||
Revision 1.56 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.55 2003/10/07 18:21:18 peter
|
||||
* fix crash
|
||||
* allow parameter subscription for register parameters
|
||||
|
||||
|
@ -35,77 +35,96 @@ unit rgcpu;
|
||||
cclasses,globtype,cgbase,rgobj;
|
||||
|
||||
type
|
||||
Tregisterallocatorcpu = class(Tregisterallocator)
|
||||
trgcpu = class(trgobj)
|
||||
procedure add_constraints(reg:Tregister);override;
|
||||
end;
|
||||
|
||||
|
||||
Trgcpu = class(Trgobj)
|
||||
trgx86fpu = class
|
||||
{ The "usableregsxxx" contain all registers of type "xxx" that }
|
||||
{ aren't currently allocated to a regvar. The "unusedregsxxx" }
|
||||
{ contain all registers of type "xxx" that aren't currently }
|
||||
{ allocated }
|
||||
unusedregsfpu,usableregsfpu : Tsuperregisterset;
|
||||
{ these counters contain the number of elements in the }
|
||||
{ unusedregsxxx/usableregsxxx sets }
|
||||
countunusedregsfpu : byte;
|
||||
countusableregsfpu : byte;
|
||||
|
||||
{ Contains the registers which are really used by the proc itself.
|
||||
It doesn't take care of registers used by called procedures
|
||||
}
|
||||
used_in_proc_other : totherregisterset;
|
||||
|
||||
{reg_pushes_other : regvarother_longintarray;
|
||||
is_reg_var_other : regvarother_booleanarray;
|
||||
regvar_loaded_other : regvarother_booleanarray;}
|
||||
|
||||
{ tries to hold the amount of times which the current tree is processed }
|
||||
t_times: longint;
|
||||
|
||||
fpuvaroffset : byte;
|
||||
|
||||
function getregisterfpu(list: taasmoutput;size:TCGSize) : tregister; override;
|
||||
procedure ungetregisterfpu(list: taasmoutput; r : tregister); override;
|
||||
constructor create;
|
||||
|
||||
{# Returns a subset register of the register r with the specified size.
|
||||
WARNING: There is no clearing of the upper parts of the register,
|
||||
if a 8-bit / 16-bit register is converted to a 32-bit register.
|
||||
It is up to the code generator to correctly zero fill the register
|
||||
}
|
||||
{ function makeregsize(reg: tregister; size: tcgsize): tregister; override;}
|
||||
function getregisterfpu(list: taasmoutput) : tregister;
|
||||
procedure ungetregisterfpu(list: taasmoutput; r : tregister);
|
||||
|
||||
{ pushes and restores registers }
|
||||
{$ifdef SUPPORT_MMX}
|
||||
procedure pushusedotherregisters(list:Taasmoutput;
|
||||
var pushed:Tpushedsavedother;
|
||||
const s:Totherregisterset);
|
||||
{$endif SUPPORT_MMX}
|
||||
{$ifdef SUPPORT_MMX}
|
||||
procedure popusedotherregisters(list:Taasmoutput;
|
||||
const pushed:Tpushedsavedother);
|
||||
{$endif SUPPORT_MMX}
|
||||
|
||||
procedure saveusedotherregisters(list:Taasmoutput;
|
||||
var saved:Tpushedsavedother;
|
||||
const s:Totherregisterset);override;
|
||||
const s:Totherregisterset);
|
||||
procedure restoreusedotherregisters(list:Taasmoutput;
|
||||
const saved:Tpushedsavedother);override;
|
||||
const saved:Tpushedsavedother);
|
||||
|
||||
procedure resetusableregisters;override;
|
||||
|
||||
{ corrects the fpu stack register by ofs }
|
||||
function correct_fpuregister(r : tregister;ofs : byte) : tregister;
|
||||
{ corrects the fpu stack register by ofs }
|
||||
function correct_fpuregister(r : tregister;ofs : byte) : tregister;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
systems,
|
||||
globals,verbose;
|
||||
verbose;
|
||||
|
||||
{************************************************************************
|
||||
tregisterallocatorcpu
|
||||
trgcpu
|
||||
*************************************************************************}
|
||||
|
||||
procedure Tregisterallocatorcpu.add_constraints(reg:Tregister);
|
||||
var
|
||||
supreg : tsuperregister;
|
||||
begin
|
||||
if getsubreg(reg) in [R_SUBL,R_SUBH] then
|
||||
begin
|
||||
supreg:=getsupreg(reg);
|
||||
{These registers have no 8-bit subregister, so add interferences.}
|
||||
add_edge(supreg,RS_ESI);
|
||||
add_edge(supreg,RS_EDI);
|
||||
add_edge(supreg,RS_EBP);
|
||||
end;
|
||||
end;
|
||||
procedure trgcpu.add_constraints(reg:Tregister);
|
||||
var
|
||||
supreg : tsuperregister;
|
||||
begin
|
||||
if getsubreg(reg) in [R_SUBL,R_SUBH] then
|
||||
begin
|
||||
supreg:=getsupreg(reg);
|
||||
{These registers have no 8-bit subregister, so add interferences.}
|
||||
add_edge(supreg,RS_ESI);
|
||||
add_edge(supreg,RS_EDI);
|
||||
add_edge(supreg,RS_EBP);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{************************************************************************
|
||||
trgcpu
|
||||
*************************************************************************}
|
||||
{******************************************************************************
|
||||
Trgobj
|
||||
******************************************************************************}
|
||||
|
||||
function trgcpu.getregisterfpu(list: taasmoutput;size: TCGSize) : tregister;
|
||||
constructor Trgx86fpu.create;
|
||||
|
||||
var i:Tsuperregister;
|
||||
|
||||
begin
|
||||
used_in_proc_other:=[];
|
||||
t_times := 0;
|
||||
countusableregsfpu:=c_countusableregsfpu;
|
||||
unusedregsfpu:=usableregsfpu;
|
||||
countunusedregsfpu:=countusableregsfpu;
|
||||
end;
|
||||
|
||||
|
||||
function trgx86fpu.getregisterfpu(list: taasmoutput) : tregister;
|
||||
|
||||
begin
|
||||
{ note: don't return R_ST0, see comments above implementation of }
|
||||
@ -114,7 +133,7 @@ unit rgcpu;
|
||||
end;
|
||||
|
||||
|
||||
procedure trgcpu.ungetregisterfpu(list : taasmoutput; r : tregister);
|
||||
procedure trgx86fpu.ungetregisterfpu(list : taasmoutput; r : tregister);
|
||||
|
||||
begin
|
||||
{ nothing to do, fpu stack management is handled by the load/ }
|
||||
@ -122,132 +141,115 @@ unit rgcpu;
|
||||
end;
|
||||
|
||||
|
||||
{$ifdef SUPPORT_MMX}
|
||||
procedure trgcpu.pushusedotherregisters(list:Taasmoutput;
|
||||
var pushed:Tpushedsavedother;
|
||||
const s:Totherregisterset);
|
||||
|
||||
{ var r:Toldregister;
|
||||
r2:Tregister;
|
||||
hr:Treference;}
|
||||
function trgx86fpu.correct_fpuregister(r : tregister;ofs : byte) : tregister;
|
||||
|
||||
begin
|
||||
(* used_in_proc_other:=used_in_proc_other+s;
|
||||
for r:=R_MM0 to R_MM6 do
|
||||
begin
|
||||
pushed[r].pushed:=false;
|
||||
{ if the register is used by the calling subroutine }
|
||||
if not is_reg_var_other[r] and
|
||||
(r in s) and
|
||||
{ and is present in use }
|
||||
not(r in unusedregsmm) then
|
||||
begin
|
||||
r2.enum:=R_INTREGISTER;
|
||||
r2.number:=NR_ESP;
|
||||
list.concat(Taicpu.Op_const_reg(A_SUB,S_L,8,r2));
|
||||
reference_reset_base(hr,r2,0);
|
||||
r2.enum:=r;
|
||||
list.concat(Taicpu.Op_reg_ref(A_MOVQ,S_NO,r2,hr));
|
||||
include(unusedregsmm,r);
|
||||
pushed[r].pushed:=true;
|
||||
end;
|
||||
end;*)
|
||||
{$ifdef TEMPREGDEBUG}
|
||||
testregisters;
|
||||
{$endif TEMPREGDEBUG}
|
||||
end;
|
||||
{$endif SUPPORT_MMX}
|
||||
|
||||
|
||||
{$ifdef SUPPORT_MMX}
|
||||
procedure trgcpu.popusedotherregisters(list:Taasmoutput;
|
||||
const pushed:Tpushedsavedother);
|
||||
|
||||
{ var r:Toldregister;
|
||||
r2,r3:Tregister;
|
||||
hr:Treference;}
|
||||
|
||||
begin
|
||||
{ restore in reverse order: }
|
||||
{ for r:=R_MM6 downto R_MM0 do
|
||||
if pushed[r].pushed then
|
||||
begin
|
||||
r2.enum:=R_INTREGISTER;
|
||||
r2.number:=NR_ESP;
|
||||
reference_reset_base(hr,r2,0);
|
||||
r3.enum:=r;
|
||||
list.concat(Taicpu.op_ref_reg(A_MOVQ,S_NO,hr,r3));
|
||||
list.concat(Taicpu.op_const_reg(A_ADD,S_L,8,r2));
|
||||
exclude(unusedregsmm,r);
|
||||
end;}
|
||||
{$ifdef TEMPREGDEBUG}
|
||||
testregisters;
|
||||
{$endif TEMPREGDEBUG}
|
||||
end;
|
||||
{$endif SUPPORT_MMX}
|
||||
|
||||
|
||||
|
||||
procedure trgcpu.saveusedotherregisters(list:Taasmoutput;var saved:Tpushedsavedother;
|
||||
const s:totherregisterset);
|
||||
|
||||
begin
|
||||
{$ifdef SUPPORT_MMX}
|
||||
if (aktoptprocessor in [class386,classP5]) or
|
||||
(CS_LittleSize in aktglobalswitches) then
|
||||
pushusedotherregisters(list,saved,s)
|
||||
else
|
||||
{$endif SUPPORT_MMX}
|
||||
inherited saveusedotherregisters(list,saved,s);
|
||||
end;
|
||||
|
||||
|
||||
procedure trgcpu.restoreusedotherregisters(list:Taasmoutput;
|
||||
const saved:tpushedsavedother);
|
||||
|
||||
begin
|
||||
{$ifdef SUPPORT_MMX}
|
||||
if (aktoptprocessor in [class386,classP5]) or
|
||||
(CS_LittleSize in aktglobalswitches) then
|
||||
popusedotherregisters(list,saved)
|
||||
else
|
||||
{$endif SUPPORT_MMX}
|
||||
inherited restoreusedotherregisters(list,saved);
|
||||
end;
|
||||
|
||||
|
||||
procedure trgcpu.resetusableregisters;
|
||||
|
||||
begin
|
||||
inherited resetusableregisters;
|
||||
fpuvaroffset := 0;
|
||||
end;
|
||||
|
||||
|
||||
function trgcpu.correct_fpuregister(r : tregister;ofs : byte) : tregister;
|
||||
|
||||
begin
|
||||
begin
|
||||
correct_fpuregister:=r;
|
||||
setsupreg(correct_fpuregister,ofs);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure trgx86fpu.saveusedotherregisters(list: taasmoutput;
|
||||
var saved : tpushedsavedother; const s: totherregisterset);
|
||||
|
||||
var
|
||||
r : tregister;
|
||||
hr : treference;
|
||||
|
||||
begin
|
||||
used_in_proc_other:=used_in_proc_other + s;
|
||||
|
||||
{$warning TODO firstsavefpureg}
|
||||
(*
|
||||
{ don't try to save the fpu registers if not desired (e.g. for }
|
||||
{ the 80x86) }
|
||||
if firstsavefpureg <> R_NO then
|
||||
for r.enum:=firstsavefpureg to lastsavefpureg do
|
||||
begin
|
||||
saved[r.enum].ofs:=reg_not_saved;
|
||||
{ if the register is used by the calling subroutine and if }
|
||||
{ it's not a regvar (those are handled separately) }
|
||||
if not is_reg_var_other[r.enum] and
|
||||
(r.enum in s) and
|
||||
{ and is present in use }
|
||||
not(r.enum in unusedregsfpu) then
|
||||
begin
|
||||
{ then save it }
|
||||
tg.GetTemp(list,extended_size,tt_persistent,hr);
|
||||
saved[r.enum].ofs:=hr.offset;
|
||||
cg.a_loadfpu_reg_ref(list,OS_FLOAT,r,hr);
|
||||
cg.a_reg_dealloc(list,r);
|
||||
include(unusedregsfpu,r.enum);
|
||||
inc(countunusedregsfpu);
|
||||
end;
|
||||
end;
|
||||
*)
|
||||
end;
|
||||
|
||||
|
||||
procedure trgx86fpu.restoreusedotherregisters(list : taasmoutput;
|
||||
const saved : tpushedsavedother);
|
||||
|
||||
var
|
||||
r,r2 : tregister;
|
||||
hr : treference;
|
||||
|
||||
begin
|
||||
{$warning TODO firstsavefpureg}
|
||||
(*
|
||||
if firstsavefpureg <> R_NO then
|
||||
for r.enum:=lastsavefpureg downto firstsavefpureg do
|
||||
begin
|
||||
if saved[r.enum].ofs <> reg_not_saved then
|
||||
begin
|
||||
r2.enum:=R_INTREGISTER;
|
||||
r2.number:=NR_FRAME_POINTER_REG;
|
||||
reference_reset_base(hr,r2,saved[r.enum].ofs);
|
||||
cg.a_reg_alloc(list,r);
|
||||
cg.a_loadfpu_ref_reg(list,OS_FLOAT,hr,r);
|
||||
if not (r.enum in unusedregsfpu) then
|
||||
{ internalerror(10)
|
||||
in n386cal we always save/restore the reg *state*
|
||||
using save/restoreunusedstate -> the current state
|
||||
may not be real (JM) }
|
||||
else
|
||||
begin
|
||||
dec(countunusedregsfpu);
|
||||
exclude(unusedregsfpu,r.enum);
|
||||
end;
|
||||
tg.UnGetTemp(list,hr);
|
||||
end;
|
||||
end;
|
||||
*)
|
||||
end;
|
||||
|
||||
(*
|
||||
function trgcpu.makeregsize(reg: tregister; size: tcgsize): tregister;
|
||||
procedure Trgx86fpu.saveotherregvars(list: taasmoutput; const s: totherregisterset);
|
||||
var
|
||||
subreg : tsubregister;
|
||||
r: Tregister;
|
||||
begin
|
||||
if getregtype(reg)<>R_INTREGISTER then
|
||||
internalerror(200306032);
|
||||
subreg:=cgsize2subreg(size);
|
||||
result:=reg;
|
||||
setsubreg(result,subreg);
|
||||
add_constraints(result);
|
||||
if not(cs_regvars in aktglobalswitches) then
|
||||
exit;
|
||||
if firstsavefpureg <> NR_NO then
|
||||
for r.enum := firstsavefpureg to lastsavefpureg do
|
||||
if is_reg_var_other[r.enum] and
|
||||
(r.enum in s) then
|
||||
store_regvar(list,r);
|
||||
end;
|
||||
*)
|
||||
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.37 2003-10-09 21:31:37 daniel
|
||||
Revision 1.38 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.37 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.36 2003/10/01 20:34:49 peter
|
||||
|
@ -178,7 +178,7 @@ implementation
|
||||
symconst,symdef,symsym,symutil,defutil,defcmp,
|
||||
pass_1,
|
||||
nld,ncal,nflw,
|
||||
rgobj,procinfo
|
||||
procinfo
|
||||
;
|
||||
|
||||
|
||||
@ -833,7 +833,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.63 2003-10-01 20:34:48 peter
|
||||
Revision 1.64 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.63 2003/10/01 20:34:48 peter
|
||||
* procinfo unit contains tprocinfo
|
||||
* cginfo renamed to cgbase
|
||||
* moved cgmessage to verbose
|
||||
|
@ -69,7 +69,7 @@ interface
|
||||
symconst,symdef,paramgr,
|
||||
aasmbase,aasmtai,aasmcpu,defutil,htypechk,
|
||||
cgbase,cpuinfo,pass_1,pass_2,regvars,
|
||||
ncon,nset,ncgutil,tgobj,rgobj,cgobj,
|
||||
ncon,nset,ncgutil,tgobj,cgobj,
|
||||
{$ifdef cpu64bit}
|
||||
cg64f64
|
||||
{$else cpu64bit}
|
||||
@ -735,7 +735,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.20 2003-10-01 20:34:48 peter
|
||||
Revision 1.21 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.20 2003/10/01 20:34:48 peter
|
||||
* procinfo unit contains tprocinfo
|
||||
* cginfo renamed to cgbase
|
||||
* moved cgmessage to verbose
|
||||
|
@ -72,7 +72,7 @@ interface
|
||||
aasmbase,aasmtai,aasmcpu,symsym,
|
||||
defutil,
|
||||
nflw,pass_2,
|
||||
cgbase,procinfo,cgobj,tgobj,rgobj
|
||||
cgbase,procinfo,cgobj,tgobj
|
||||
;
|
||||
|
||||
{*****************************************************************************
|
||||
@ -372,7 +372,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.43 2003-10-09 21:31:37 daniel
|
||||
Revision 1.44 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.43 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.42 2003/10/07 18:18:16 peter
|
||||
|
@ -92,7 +92,6 @@ implementation
|
||||
cga,cgx86,
|
||||
{$endif x86}
|
||||
ncgutil,cgobj,tgobj,
|
||||
rgobj,rgcpu,
|
||||
procinfo;
|
||||
|
||||
|
||||
@ -573,7 +572,6 @@ implementation
|
||||
var
|
||||
regs_to_push_other : totherregisterset;
|
||||
regs_to_alloc,regs_to_free:Tsuperregisterset;
|
||||
pushedother : tpushedsavedother;
|
||||
oldpushedparasize : longint;
|
||||
{ adress returned from an I/O-error }
|
||||
{ help reference pointer }
|
||||
@ -756,6 +754,7 @@ implementation
|
||||
freeparas;
|
||||
|
||||
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
|
||||
cg.allocexplicitregisters(exprasmlist,R_MMXREGISTER,paramanager.get_volatile_registers_mmx(procdefinition.proccalloption));
|
||||
|
||||
{ call method }
|
||||
cg.a_call_reg(exprasmlist,pvreg);
|
||||
@ -771,6 +770,8 @@ implementation
|
||||
freeparas;
|
||||
|
||||
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
|
||||
cg.allocexplicitregisters(exprasmlist,R_MMXREGISTER,paramanager.get_volatile_registers_mmx(procdefinition.proccalloption));
|
||||
|
||||
{ Calling interrupt from the same code requires some
|
||||
extra code }
|
||||
if (po_interrupt in procdefinition.procoptions) then
|
||||
@ -804,6 +805,7 @@ implementation
|
||||
freeparas;
|
||||
|
||||
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
|
||||
cg.allocexplicitregisters(exprasmlist,R_MMXREGISTER,paramanager.get_volatile_registers_mmx(procdefinition.proccalloption));
|
||||
|
||||
{ Calling interrupt from the same code requires some
|
||||
extra code }
|
||||
@ -855,6 +857,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
cg.deallocexplicitregisters(exprasmlist,R_MMXREGISTER,paramanager.get_volatile_registers_mmx(procdefinition.proccalloption));
|
||||
cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_free);
|
||||
|
||||
{ handle function results }
|
||||
@ -908,7 +911,6 @@ implementation
|
||||
|
||||
procedure tcgcallnode.inlined_pass_2;
|
||||
var
|
||||
unusedstate: pointer;
|
||||
oldaktcallnode : tcallnode;
|
||||
oldprocinfo : tprocinfo;
|
||||
oldinlining_procedure : boolean;
|
||||
@ -1102,7 +1104,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.128 2003-10-10 09:21:53 marco
|
||||
Revision 1.129 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.128 2003/10/10 09:21:53 marco
|
||||
* typo fix from Wiktor
|
||||
|
||||
Revision 1.127 2003/10/09 21:31:37 daniel
|
||||
|
@ -69,7 +69,7 @@ interface
|
||||
procinfo,cgbase,
|
||||
cgobj,
|
||||
ncgutil,
|
||||
tgobj,rgobj
|
||||
tgobj
|
||||
;
|
||||
|
||||
|
||||
@ -515,7 +515,14 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.48 2003-10-09 21:31:37 daniel
|
||||
Revision 1.49 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.48 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.47 2003/10/01 20:34:48 peter
|
||||
|
@ -67,7 +67,7 @@ implementation
|
||||
verbose,globals,
|
||||
symconst,symdef,aasmbase,aasmtai,aasmcpu,defutil,
|
||||
cpuinfo,cpubase,
|
||||
cgbase,tgobj,rgobj
|
||||
cgbase,tgobj,cgobj
|
||||
{$ifdef delphi}
|
||||
,dmisc
|
||||
{$endif}
|
||||
@ -554,7 +554,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.31 2003-10-01 20:34:48 peter
|
||||
Revision 1.32 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.31 2003/10/01 20:34:48 peter
|
||||
* procinfo unit contains tprocinfo
|
||||
* cginfo renamed to cgbase
|
||||
* moved cgmessage to verbose
|
||||
|
@ -90,7 +90,7 @@ implementation
|
||||
cpubase,cpuinfo,
|
||||
nld,ncon,
|
||||
ncgutil,
|
||||
tgobj,rgobj,paramgr,
|
||||
tgobj,paramgr,
|
||||
regvars,cgobj
|
||||
{$ifndef cpu64bit}
|
||||
,cg64f32
|
||||
@ -176,6 +176,7 @@ implementation
|
||||
var
|
||||
hl,otlabel,oflabel : tasmlabel;
|
||||
{$ifdef i386}
|
||||
(*
|
||||
org_regvar_loaded_other,
|
||||
then_regvar_loaded_other,
|
||||
else_regvar_loaded_other : regvarother_booleanarray;
|
||||
@ -185,6 +186,7 @@ implementation
|
||||
org_list,
|
||||
then_list,
|
||||
else_list : taasmoutput;
|
||||
*)
|
||||
{$endif i386}
|
||||
|
||||
begin
|
||||
@ -197,6 +199,7 @@ implementation
|
||||
secondpass(left);
|
||||
|
||||
{$ifdef i386}
|
||||
(*
|
||||
{ save regvars loaded in the beginning so that we can restore them }
|
||||
{ when processing the else-block }
|
||||
if cs_regvars in aktglobalswitches then
|
||||
@ -204,15 +207,18 @@ implementation
|
||||
org_list := exprasmlist;
|
||||
exprasmlist := taasmoutput.create;
|
||||
end;
|
||||
*)
|
||||
{$endif i386}
|
||||
maketojumpbool(exprasmlist,left,lr_dont_load_regvars);
|
||||
|
||||
{$ifdef i386}
|
||||
(*
|
||||
if cs_regvars in aktglobalswitches then
|
||||
begin
|
||||
{ org_regvar_loaded_int := rg.regvar_loaded_int;
|
||||
org_regvar_loaded_other := rg.regvar_loaded_other;}
|
||||
org_regvar_loaded_int := rg.regvar_loaded_int;
|
||||
org_regvar_loaded_other := rg.regvar_loaded_other;
|
||||
end;
|
||||
*)
|
||||
{$endif i386}
|
||||
|
||||
if assigned(right) then
|
||||
@ -241,19 +247,24 @@ implementation
|
||||
begin
|
||||
objectlibrary.getlabel(hl);
|
||||
{ do go back to if line !! }
|
||||
(*
|
||||
{$ifdef i386}
|
||||
if not(cs_regvars in aktglobalswitches) then
|
||||
{$endif i386}
|
||||
*)
|
||||
aktfilepos:=exprasmList.getlasttaifilepos^
|
||||
(*
|
||||
{$ifdef i386}
|
||||
else
|
||||
aktfilepos:=then_list.getlasttaifilepos^
|
||||
{$endif i386}
|
||||
*)
|
||||
;
|
||||
cg.a_jmp_always(exprasmlist,hl);
|
||||
end;
|
||||
cg.a_label(exprasmlist,falselabel);
|
||||
secondpass(t1);
|
||||
(*
|
||||
{$ifdef i386}
|
||||
{ save current asmlist (previous instructions + else-block) }
|
||||
{ and loaded regvar state and create a new clean list }
|
||||
@ -265,11 +276,13 @@ implementation
|
||||
exprasmlist := taasmoutput.create;
|
||||
end;
|
||||
{$endif i386}
|
||||
*)
|
||||
if assigned(right) then
|
||||
cg.a_label(exprasmlist,hl);
|
||||
end
|
||||
else
|
||||
begin
|
||||
(*
|
||||
{$ifdef i386}
|
||||
if cs_regvars in aktglobalswitches then
|
||||
begin
|
||||
@ -279,6 +292,7 @@ implementation
|
||||
exprasmlist := taasmoutput.create;
|
||||
end;
|
||||
{$endif i386}
|
||||
*)
|
||||
cg.a_label(exprasmlist,falselabel);
|
||||
end;
|
||||
if not(assigned(right)) then
|
||||
@ -286,6 +300,7 @@ implementation
|
||||
cg.a_label(exprasmlist,truelabel);
|
||||
end;
|
||||
|
||||
(*
|
||||
{$ifdef i386}
|
||||
if cs_regvars in aktglobalswitches then
|
||||
begin
|
||||
@ -320,6 +335,8 @@ implementation
|
||||
exprasmlist := org_list;
|
||||
end;
|
||||
{$endif i386}
|
||||
*)
|
||||
|
||||
truelabel:=otlabel;
|
||||
falselabel:=oflabel;
|
||||
end;
|
||||
@ -1444,7 +1461,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.83 2003-10-09 21:31:37 daniel
|
||||
Revision 1.84 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.83 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.82 2003/10/01 20:34:48 peter
|
||||
|
@ -59,7 +59,7 @@ implementation
|
||||
cgbase,pass_1,pass_2,
|
||||
cpuinfo,cpubase,paramgr,procinfo,
|
||||
nbas,ncon,ncal,ncnv,nld,
|
||||
tgobj,ncgutil,cgobj,rgobj
|
||||
tgobj,ncgutil,cgobj
|
||||
{$ifndef cpu64bit}
|
||||
,cg64f32
|
||||
{$endif cpu64bit}
|
||||
@ -656,7 +656,14 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.46 2003-10-09 21:31:37 daniel
|
||||
Revision 1.47 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.46 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.45 2003/10/08 19:19:45 peter
|
||||
|
@ -50,12 +50,12 @@ implementation
|
||||
cutils,
|
||||
systems,
|
||||
verbose,globtype,globals,
|
||||
symconst,symtype,symdef,symsym,symtable,defutil,paramgr,
|
||||
symconst,symtype,symdef,symsym,defutil,paramgr,
|
||||
ncnv,ncon,nmem,nbas,
|
||||
aasmbase,aasmtai,aasmcpu,regvars,
|
||||
aasmbase,aasmtai,
|
||||
cgbase,pass_2,
|
||||
cpubase,cpuinfo,procinfo,
|
||||
tgobj,ncgutil,cgobj,rgobj,ncgbas;
|
||||
cpubase,cpuinfo,
|
||||
tgobj,ncgutil,cgobj,ncgbas;
|
||||
|
||||
{*****************************************************************************
|
||||
SecondLoad
|
||||
@ -884,7 +884,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.92 2003-10-09 21:31:37 daniel
|
||||
Revision 1.93 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.92 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.91 2003/10/07 15:17:07 peter
|
||||
|
@ -124,7 +124,7 @@ implementation
|
||||
pass_1,pass_2,
|
||||
ncon,
|
||||
cpuinfo,
|
||||
tgobj,ncgutil,cgobj,rgobj,paramgr,cg64f32;
|
||||
tgobj,ncgutil,cgobj,paramgr,cg64f32;
|
||||
|
||||
{*****************************************************************************
|
||||
TCGUNARYMINUSNODE
|
||||
@ -502,7 +502,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.20 2003-10-09 21:31:37 daniel
|
||||
Revision 1.21 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.20 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.19 2003/10/01 20:34:48 peter
|
||||
|
@ -90,11 +90,11 @@ implementation
|
||||
{$endif GDB}
|
||||
globtype,systems,
|
||||
cutils,verbose,globals,
|
||||
symconst,symdef,symsym,symtable,defutil,paramgr,
|
||||
symconst,symdef,symsym,defutil,paramgr,
|
||||
aasmbase,aasmtai,
|
||||
procinfo,pass_2,
|
||||
pass_1,nld,ncon,nadd,
|
||||
cgobj,tgobj,rgobj,ncgutil,symbase
|
||||
cgobj,tgobj,ncgutil,symbase
|
||||
;
|
||||
|
||||
|
||||
@ -876,7 +876,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.78 2003-10-09 21:31:37 daniel
|
||||
Revision 1.79 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.78 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.77 2003/10/01 20:34:48 peter
|
||||
|
@ -44,7 +44,7 @@ uses
|
||||
aasmbase,aasmtai,
|
||||
ncnv, ncon, pass_2,
|
||||
cgbase, cpubase,
|
||||
tgobj, rgobj, cgobj, ncgutil;
|
||||
tgobj, cgobj, ncgutil;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
@ -201,7 +201,14 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.10 2003-10-09 21:31:37 daniel
|
||||
Revision 1.11 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.10 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.9 2003/10/01 20:34:48 peter
|
||||
|
@ -89,7 +89,7 @@ implementation
|
||||
paramgr,
|
||||
pass_2,
|
||||
nbas,ncon,nflw,
|
||||
tgobj,ncgutil,regvars,rgobj,cpuinfo;
|
||||
ncgutil,regvars,cpuinfo;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
@ -1003,7 +1003,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.50 2003-10-09 21:31:37 daniel
|
||||
Revision 1.51 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.50 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.49 2003/10/01 20:34:48 peter
|
||||
|
@ -33,9 +33,9 @@ interface
|
||||
aasmbase,aasmtai,aasmcpu,
|
||||
symconst,symbase,symdef,symsym,symtype,symtable,
|
||||
{$ifndef cpu64bit}
|
||||
cg64f32,
|
||||
cg64f32
|
||||
{$endif cpu64bit}
|
||||
rgobj;
|
||||
;
|
||||
|
||||
type
|
||||
tloadregvars = (lr_dont_load_regvars, lr_load_regvars);
|
||||
@ -1948,7 +1948,14 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.157 2003-10-09 21:31:37 daniel
|
||||
Revision 1.158 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.157 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.156 2003/10/07 18:18:16 peter
|
||||
|
@ -145,7 +145,7 @@ implementation
|
||||
cutils,verbose,globtype,globals,systems,
|
||||
symtable,symnot,
|
||||
defutil,defcmp,
|
||||
htypechk,pass_1,procinfo,paramgr,rgobj,
|
||||
htypechk,pass_1,procinfo,paramgr,
|
||||
ncon,ninl,ncnv,nmem,ncal,cpubase,cgobj,cgbase
|
||||
;
|
||||
|
||||
@ -1245,7 +1245,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.111 2003-10-09 21:31:37 daniel
|
||||
Revision 1.112 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.111 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.110 2003/10/08 19:19:45 peter
|
||||
|
@ -154,7 +154,7 @@ implementation
|
||||
{$endif GDB}
|
||||
aasmcpu,
|
||||
cpubase,cgbase,
|
||||
cgobj,rgobj
|
||||
cgobj
|
||||
;
|
||||
|
||||
|
||||
@ -1356,7 +1356,14 @@ initialization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.51 2003-10-07 21:14:32 peter
|
||||
Revision 1.52 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.51 2003/10/07 21:14:32 peter
|
||||
* compare_paras() has a parameter to ignore hidden parameters
|
||||
* cross unit overload searching ignores hidden parameters when
|
||||
comparing parameter lists. Now function(string):string is
|
||||
|
@ -73,6 +73,8 @@ unit paramgr;
|
||||
function get_para_align(calloption : tproccalloption):byte;virtual;
|
||||
function get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;virtual;
|
||||
function get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset;virtual;
|
||||
function get_volatile_registers_mmx(calloption : tproccalloption):tsuperregisterset;virtual;
|
||||
function get_volatile_registers_mm(calloption : tproccalloption):tsuperregisterset;virtual;
|
||||
function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;virtual;abstract;
|
||||
|
||||
{# allocate a parameter location created with create_paraloc_info
|
||||
@ -121,9 +123,8 @@ unit paramgr;
|
||||
implementation
|
||||
|
||||
uses
|
||||
cpuinfo,globals,systems,
|
||||
symbase,symsym,
|
||||
rgobj,cgobj,
|
||||
cpuinfo,systems,
|
||||
cgobj,
|
||||
defutil,verbose;
|
||||
|
||||
{ true if uses a parameter as return value }
|
||||
@ -273,6 +274,18 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tparamanager.get_volatile_registers_mmx(calloption : tproccalloption):tsuperregisterset;
|
||||
begin
|
||||
result:=[];
|
||||
end;
|
||||
|
||||
|
||||
function tparamanager.get_volatile_registers_mm(calloption : tproccalloption):tsuperregisterset;
|
||||
begin
|
||||
result:=[];
|
||||
end;
|
||||
|
||||
|
||||
procedure tparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation);
|
||||
begin
|
||||
case loc.loc of
|
||||
@ -424,7 +437,14 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.61 2003-10-09 21:31:37 daniel
|
||||
Revision 1.62 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.61 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.60 2003/10/05 21:21:52 peter
|
||||
|
@ -55,10 +55,10 @@ implementation
|
||||
globtype,systems,verbose,
|
||||
cclasses,globals,
|
||||
symconst,symbase,symtype,symsym,paramgr,
|
||||
aasmbase,aasmtai,
|
||||
pass_1,cpubase,cgbase,
|
||||
aasmtai,
|
||||
pass_1,cgbase,
|
||||
procinfo,
|
||||
regvars,nflw,rgobj,cgobj;
|
||||
nflw,cgobj;
|
||||
|
||||
{*****************************************************************************
|
||||
SecondPass
|
||||
@ -243,10 +243,6 @@ implementation
|
||||
end;
|
||||
|
||||
procedure generatecode(var p : tnode);
|
||||
{$ifdef EXTDEBUG}
|
||||
var
|
||||
sr : tsuperregister;
|
||||
{$endif EXTDEBUG}
|
||||
begin
|
||||
flowcontrol:=[];
|
||||
{ when size optimization only count occurrence }
|
||||
@ -272,7 +268,7 @@ implementation
|
||||
end;
|
||||
|
||||
{ process register variable stuff (JM) }
|
||||
assign_regvars(p);
|
||||
{ assign_regvars(p);}
|
||||
{ load_regvars(current_procinfo.aktentrycode,p);}
|
||||
|
||||
{ for the i386 it must be done in genexitcode because it has }
|
||||
@ -304,7 +300,14 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.68 2003-10-09 21:31:37 daniel
|
||||
Revision 1.69 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.68 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.67 2003/10/01 20:34:49 peter
|
||||
|
@ -143,11 +143,8 @@ implementation
|
||||
|
||||
uses
|
||||
cutils,systems,
|
||||
cresstr,
|
||||
tgobj,rgobj,
|
||||
defutil,
|
||||
fmodule
|
||||
,symbase,paramgr
|
||||
tgobj,cgobj,
|
||||
paramgr
|
||||
;
|
||||
|
||||
|
||||
@ -217,7 +214,14 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.4 2003-10-09 21:31:37 daniel
|
||||
Revision 1.5 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.4 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.3 2003/10/05 21:21:52 peter
|
||||
|
@ -56,7 +56,7 @@ implementation
|
||||
scanner,
|
||||
pbase,pexpr,
|
||||
{ codegen }
|
||||
procinfo,rgobj,cgbase
|
||||
procinfo,cgbase
|
||||
,radirect
|
||||
{$ifdef i386}
|
||||
{$ifndef NoRa386Int}
|
||||
@ -815,7 +815,7 @@ implementation
|
||||
{ END is read, got a list of changed registers? }
|
||||
if try_to_consume(_LECKKLAMMER) then
|
||||
begin
|
||||
asmstat.used_regs_fpu:=ALL_OTHERREGISTERS;
|
||||
asmstat.used_regs_fpu:=[first_fpu_supreg..last_fpu_supreg];
|
||||
if token<>_RECKKLAMMER then
|
||||
begin
|
||||
repeat
|
||||
@ -838,7 +838,7 @@ implementation
|
||||
else
|
||||
begin
|
||||
asmstat.used_regs_int:=paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption);
|
||||
asmstat.used_regs_fpu:=ALL_OTHERREGISTERS;
|
||||
asmstat.used_regs_fpu:=paramanager.get_volatile_registers_fpu(current_procinfo.procdef.proccalloption);
|
||||
end;
|
||||
|
||||
{ mark the start and the end of the assembler block
|
||||
@ -1129,7 +1129,14 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.114 2003-10-08 19:19:45 peter
|
||||
Revision 1.115 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.114 2003/10/08 19:19:45 peter
|
||||
* set_varstate cleanup
|
||||
|
||||
Revision 1.113 2003/10/07 20:06:37 peter
|
||||
|
@ -92,7 +92,7 @@ implementation
|
||||
scanner,
|
||||
pbase,pstatmnt,pdecl,pdecsub,pexports,
|
||||
{ codegen }
|
||||
tgobj,rgobj,cgobj,
|
||||
tgobj,cgobj,
|
||||
ncgutil,regvars
|
||||
{$ifndef NOOPT}
|
||||
{$ifdef i386}
|
||||
@ -1277,7 +1277,14 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.161 2003-10-09 21:31:37 daniel
|
||||
Revision 1.162 2003-10-10 17:48:13 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.161 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.160 2003/10/09 15:20:56 peter
|
||||
|
@ -30,7 +30,7 @@ interface
|
||||
aasmbase,aasmtai,aasmcpu,
|
||||
node,
|
||||
symsym,
|
||||
cpubase, cgbase, tgobj, rgobj;
|
||||
cpubase, cgbase, tgobj;
|
||||
|
||||
procedure assign_regvars(p: tnode);
|
||||
procedure load_regvars(asml: TAAsmoutput; p: tnode);
|
||||
@ -43,10 +43,12 @@ interface
|
||||
procedure translate_regvars(list: taasmoutput; const table:Ttranstable);
|
||||
|
||||
{$ifdef i386}
|
||||
(*
|
||||
procedure sync_regvars_other(list1, list2: taasmoutput; const regvarsloaded1,
|
||||
regvarsloaded2: regvarother_booleanarray);
|
||||
procedure sync_regvars_int(list1, list2: taasmoutput; const regvarsloaded1,
|
||||
regvarsloaded2: Tsuperregisterset);
|
||||
*)
|
||||
{$endif i386}
|
||||
|
||||
implementation
|
||||
@ -56,7 +58,7 @@ implementation
|
||||
cutils,cclasses,verbose,globals,
|
||||
psub,
|
||||
symconst,symbase,symtype,symdef,paramgr,defutil,
|
||||
cpuinfo,cgobj,rgcpu,procinfo;
|
||||
cpuinfo,cgobj,procinfo;
|
||||
|
||||
|
||||
procedure searchregvars(p : tnamedindexitem;arg:pointer);
|
||||
@ -501,12 +503,12 @@ implementation
|
||||
end;
|
||||
|
||||
{$ifdef i386}
|
||||
(*
|
||||
procedure sync_regvars_other(list1, list2: taasmoutput; const regvarsloaded1,
|
||||
regvarsloaded2: regvarother_booleanarray);
|
||||
var
|
||||
counter: tregisterindex;
|
||||
begin
|
||||
(*
|
||||
for counter := low(rg.regvar_loaded_other) to high(rg.regvar_loaded_other) do
|
||||
begin
|
||||
rg.regvar_loaded_other[counter] := regvarsloaded1[counter] and
|
||||
@ -517,7 +519,6 @@ implementation
|
||||
else
|
||||
load_regvar_reg(list1,counter);
|
||||
end;
|
||||
*)
|
||||
end;
|
||||
|
||||
|
||||
@ -539,6 +540,7 @@ implementation
|
||||
load_regvar_reg(list1,r);
|
||||
end;
|
||||
end;
|
||||
*)
|
||||
{$endif i386}
|
||||
|
||||
|
||||
@ -634,7 +636,14 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.69 2003-10-09 21:31:37 daniel
|
||||
Revision 1.70 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.69 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.68 2003/10/01 20:34:49 peter
|
||||
|
@ -84,7 +84,7 @@ unit rgobj;
|
||||
uses
|
||||
cutils, cpubase,
|
||||
aasmbase,aasmtai,aasmcpu,
|
||||
cclasses,globtype,cgbase,node,cgobj,
|
||||
cclasses,globtype,cgbase,node,
|
||||
{$ifdef delphi}
|
||||
dmisc,
|
||||
{$endif}
|
||||
@ -141,86 +141,6 @@ unit rgobj;
|
||||
end;
|
||||
|
||||
|
||||
trgobj = class
|
||||
{ The "usableregsxxx" contain all registers of type "xxx" that }
|
||||
{ aren't currently allocated to a regvar. The "unusedregsxxx" }
|
||||
{ contain all registers of type "xxx" that aren't currently }
|
||||
{ allocated }
|
||||
unusedregsfpu,usableregsfpu : Tsuperregisterset;
|
||||
unusedregsmm,usableregsmm : Tsuperregisterset;
|
||||
{ these counters contain the number of elements in the }
|
||||
{ unusedregsxxx/usableregsxxx sets }
|
||||
countunusedregsfpu,
|
||||
countunusedregsmm : byte;
|
||||
countusableregsaddr,
|
||||
countusableregsfpu,
|
||||
countusableregsmm : byte;
|
||||
|
||||
{ Contains the registers which are really used by the proc itself.
|
||||
It doesn't take care of registers used by called procedures
|
||||
}
|
||||
used_in_proc_other : totherregisterset;
|
||||
|
||||
reg_pushes_other : regvarother_longintarray;
|
||||
is_reg_var_other : regvarother_booleanarray;
|
||||
regvar_loaded_other : regvarother_booleanarray;
|
||||
|
||||
{ tries to hold the amount of times which the current tree is processed }
|
||||
t_times: longint;
|
||||
|
||||
constructor create;
|
||||
|
||||
{# Allocate a floating point register.}
|
||||
function getregisterfpu(list: taasmoutput;size:Tcgsize) : tregister; virtual;
|
||||
{# Free a floating point register.}
|
||||
procedure ungetregisterfpu(list: taasmoutput; r : tregister); virtual;
|
||||
|
||||
function getregistermm(list: taasmoutput) : tregister; virtual;
|
||||
procedure ungetregistermm(list: taasmoutput; r : tregister); virtual;
|
||||
|
||||
{# Tries to allocate the passed fpu register, if possible.}
|
||||
function getexplicitregisterfpu(list : taasmoutput; r : Tregister) : tregister;virtual;
|
||||
|
||||
{# Deallocate any kind of register. }
|
||||
procedure ungetregister(list: taasmoutput; r : tregister); virtual;
|
||||
|
||||
{# Saves register variables (restoring happens automatically).}
|
||||
procedure saveotherregvars(list:Taasmoutput;const s:Totherregisterset);
|
||||
|
||||
{# Saves in temporary references (allocated via the temp. allocator)
|
||||
the registers defined in @var(s). The registers are only saved
|
||||
if they are currently in use, otherwise they are left as is.
|
||||
|
||||
On processors which have instructions which manipulate the stack,
|
||||
this routine should be overriden for performance reasons.
|
||||
|
||||
@param(list) List to add the instruction to
|
||||
@param(saved) Array of saved register information
|
||||
@param(s) Registers which might require saving
|
||||
}
|
||||
procedure saveusedotherregisters(list:Taasmoutput;
|
||||
var saved:Tpushedsavedother;
|
||||
const s:Totherregisterset);virtual;
|
||||
{# Restores the registers which were saved with a call
|
||||
to @var(saveusedregisters).
|
||||
|
||||
On processors which have instructions which manipulate the stack,
|
||||
this routine should be overriden for performance reasons.
|
||||
}
|
||||
procedure restoreusedotherregisters(list:Taasmoutput;
|
||||
const saved:Tpushedsavedother);virtual;
|
||||
|
||||
procedure resetusableregisters;virtual;
|
||||
|
||||
protected
|
||||
{ the following two contain the common (generic) code for all }
|
||||
{ get- and ungetregisterxxx functions/procedures }
|
||||
function getregistergenother(list: taasmoutput; const lowreg, highreg: tsuperregister;
|
||||
var unusedregs:Tsuperregisterset;var countunusedregs:byte): tregister;
|
||||
procedure ungetregistergen(list: taasmoutput; r: tregister;
|
||||
const usableregs:tsuperregisterset;var unusedregs: tsuperregisterset; var countunusedregs: byte);
|
||||
end;
|
||||
|
||||
{#------------------------------------------------------------------
|
||||
|
||||
This class implements the abstract register allocator. It is used by the
|
||||
@ -231,9 +151,7 @@ unit rgobj;
|
||||
by cpu-specific implementations.
|
||||
|
||||
--------------------------------------------------------------------}
|
||||
Tregisterallocator=class
|
||||
{# A register allocator is owned by a code generator.}
|
||||
owner:Tcg;
|
||||
trgobj=class
|
||||
preserved_by_proc,used_in_proc:Tsuperregisterset;
|
||||
is_reg_var:Tsuperregisterset; {old regvars}
|
||||
reg_var_loaded:Tsuperregisterset; {old regvars}
|
||||
@ -243,18 +161,19 @@ unit rgobj;
|
||||
|
||||
constructor create(Acpu_registers:byte;
|
||||
Aregtype:Tregistertype;
|
||||
Adefaultsub:Tsubregister;
|
||||
const Ausable:string;
|
||||
Afirst_imaginary:Tsuperregister;
|
||||
Apreserved_by_proc:Tsuperregisterset);
|
||||
destructor destroy;override;
|
||||
{# Allocate a register. An internalerror will be generated if there is
|
||||
no more free registers which can be allocated.}
|
||||
function getregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
function getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;
|
||||
procedure add_constraints(reg:Tregister);virtual;
|
||||
{# Allocate an ABT register. An internalerror will be generated if there
|
||||
are no more free registers that can be allocated. An explanantion of
|
||||
abt registers can be found near the implementation.}
|
||||
function getabtregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
function getabtregister(list:Taasmoutput;subreg:Tsubregister):Tregister;
|
||||
{# Get the register specified.}
|
||||
procedure getexplicitregister(list:Taasmoutput;r:Tregister);
|
||||
{# Get multiple registers specified.}
|
||||
@ -287,6 +206,8 @@ unit rgobj;
|
||||
procedure add_edge(u,v:Tsuperregister);
|
||||
protected
|
||||
regtype:Tregistertype;
|
||||
{ default subregister used }
|
||||
defaultsub:tsubregister;
|
||||
{# First imaginary register.}
|
||||
first_imaginary,
|
||||
{# Last register allocated.}
|
||||
@ -337,41 +258,21 @@ unit rgobj;
|
||||
maxspillingcounter = 20;
|
||||
|
||||
|
||||
{ trerefence handling }
|
||||
|
||||
{# Clear to zero a treference }
|
||||
procedure reference_reset(var ref : treference);
|
||||
{# Clear to zero a treference, and set is base address
|
||||
to base register.
|
||||
}
|
||||
procedure reference_reset_base(var ref : treference;base : tregister;offset : longint);
|
||||
procedure reference_reset_symbol(var ref : treference;sym : tasmsymbol;offset : longint);
|
||||
procedure reference_release(list: taasmoutput; const ref : treference);
|
||||
{ This routine verifies if two references are the same, and
|
||||
if so, returns TRUE, otherwise returns false.
|
||||
}
|
||||
function references_equal(sref : treference;dref : treference) : boolean;
|
||||
|
||||
{ tlocation handling }
|
||||
procedure location_reset(var l : tlocation;lt:TCGLoc;lsize:TCGSize);
|
||||
procedure location_release(list: taasmoutput; const l : tlocation);
|
||||
procedure location_freetemp(list: taasmoutput; const l : tlocation);
|
||||
procedure location_copy(var destloc:tlocation; const sourceloc : tlocation);
|
||||
procedure location_swap(var destloc,sourceloc : tlocation);
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
systems,{$ifdef EXTDEBUG}fmodule,{$endif}
|
||||
globals,verbose,tgobj,regvars,procinfo;
|
||||
systems,
|
||||
globals,verbose,tgobj,procinfo;
|
||||
|
||||
{******************************************************************************
|
||||
Tregisterallocator
|
||||
trgobj
|
||||
******************************************************************************}
|
||||
|
||||
constructor Tregisterallocator.create(Acpu_registers:byte;
|
||||
constructor trgobj.create(Acpu_registers:byte;
|
||||
Aregtype:Tregistertype;
|
||||
Adefaultsub:Tsubregister;
|
||||
const Ausable:string;
|
||||
Afirst_imaginary:Tsuperregister;
|
||||
Apreserved_by_proc:Tsuperregisterset);
|
||||
@ -386,6 +287,7 @@ implementation
|
||||
first_imaginary:=Afirst_imaginary;
|
||||
cpu_registers:=Acpu_registers;
|
||||
regtype:=Aregtype;
|
||||
defaultsub:=Adefaultsub;
|
||||
unusedregs:=[first_reg..last_reg]; { 255 (RS_INVALID) can't be used }
|
||||
{$ifdef powerpc}
|
||||
preserved_by_proc:=[RS_R13..RS_R31];
|
||||
@ -405,7 +307,7 @@ implementation
|
||||
fillchar(colour,sizeof(colour),RS_INVALID);
|
||||
end;
|
||||
|
||||
destructor Tregisterallocator.destroy;
|
||||
destructor trgobj.destroy;
|
||||
|
||||
var i:Tsuperregister;
|
||||
|
||||
@ -421,14 +323,12 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function Tregisterallocator.getregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
function trgobj.getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;
|
||||
var i,p:Tsuperregister;
|
||||
r:Tregister;
|
||||
min : byte;
|
||||
adj : pstring;
|
||||
subreg:Tsubregister;
|
||||
begin
|
||||
subreg:=cgsize2subreg(size);
|
||||
if maxreg<last_reg then
|
||||
begin
|
||||
inc(maxreg);
|
||||
@ -481,7 +381,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure Tregisterallocator.ungetregister(list:Taasmoutput;r:Tregister);
|
||||
procedure trgobj.ungetregister(list:Taasmoutput;r:Tregister);
|
||||
|
||||
var supreg:Tsuperregister;
|
||||
|
||||
@ -497,7 +397,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure Tregisterallocator.getexplicitregister(list:Taasmoutput;r:Tregister);
|
||||
procedure trgobj.getexplicitregister(list:Taasmoutput;r:Tregister);
|
||||
|
||||
var supreg:Tsuperregister;
|
||||
|
||||
@ -519,7 +419,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure Tregisterallocator.allocexplicitregisters(list:Taasmoutput;r:Tsuperregisterset);
|
||||
procedure trgobj.allocexplicitregisters(list:Taasmoutput;r:Tsuperregisterset);
|
||||
|
||||
var reg:Tregister;
|
||||
i:Tsuperregister;
|
||||
@ -544,7 +444,7 @@ implementation
|
||||
;
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.deallocexplicitregisters(list:Taasmoutput;r:Tsuperregisterset);
|
||||
procedure trgobj.deallocexplicitregisters(list:Taasmoutput;r:Tsuperregisterset);
|
||||
|
||||
var reg:Tregister;
|
||||
i:Tsuperregister;
|
||||
@ -565,7 +465,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure Tregisterallocator.do_register_allocation(list:Taasmoutput;headertai:tai);
|
||||
procedure trgobj.do_register_allocation(list:Taasmoutput;headertai:tai);
|
||||
|
||||
var spillingcounter:byte;
|
||||
fastspill:boolean;
|
||||
@ -589,13 +489,13 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure Tregisterallocator.add_constraints(reg:Tregister);
|
||||
procedure trgobj.add_constraints(reg:Tregister);
|
||||
|
||||
begin
|
||||
end;
|
||||
|
||||
|
||||
procedure Tregisterallocator.add_edge(u,v:Tsuperregister);
|
||||
procedure trgobj.add_edge(u,v:Tsuperregister);
|
||||
|
||||
{This procedure will add an edge to the virtual interference graph.}
|
||||
|
||||
@ -632,7 +532,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure Tregisterallocator.add_edges_used(u:Tsuperregister);
|
||||
procedure trgobj.add_edges_used(u:Tsuperregister);
|
||||
|
||||
var i:Tsuperregister;
|
||||
|
||||
@ -643,7 +543,7 @@ implementation
|
||||
end;
|
||||
|
||||
{$ifdef EXTDEBUG}
|
||||
procedure Tregisterallocator.writegraph(loopidx:longint);
|
||||
procedure trgobj.writegraph(loopidx:longint);
|
||||
|
||||
{This procedure writes out the current interference graph in the
|
||||
register allocator.}
|
||||
@ -680,7 +580,7 @@ implementation
|
||||
end;
|
||||
{$endif EXTDEBUG}
|
||||
|
||||
procedure Tregisterallocator.add_to_movelist(u:Tsuperregister;data:Tlinkedlistitem);
|
||||
procedure trgobj.add_to_movelist(u:Tsuperregister;data:Tlinkedlistitem);
|
||||
|
||||
begin
|
||||
if movelist[u]=nil then
|
||||
@ -694,7 +594,7 @@ implementation
|
||||
inc(movelist[u]^.count);
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.add_move_instruction(instr:Taicpu);
|
||||
procedure trgobj.add_move_instruction(instr:Taicpu);
|
||||
|
||||
{This procedure notifies a certain as a move instruction so the
|
||||
register allocator can try to eliminate it.}
|
||||
@ -717,7 +617,7 @@ implementation
|
||||
i.y:=dsupreg;
|
||||
end;
|
||||
|
||||
function Tregisterallocator.move_related(n:Tsuperregister):boolean;
|
||||
function trgobj.move_related(n:Tsuperregister):boolean;
|
||||
|
||||
var i:cardinal;
|
||||
|
||||
@ -735,7 +635,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.make_work_list;
|
||||
procedure trgobj.make_work_list;
|
||||
|
||||
var n:Tsuperregister;
|
||||
|
||||
@ -751,7 +651,7 @@ implementation
|
||||
simplifyworklist:=simplifyworklist+char(n);
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.prepare_colouring;
|
||||
procedure trgobj.prepare_colouring;
|
||||
|
||||
begin
|
||||
make_work_list;
|
||||
@ -764,7 +664,7 @@ implementation
|
||||
selectstack:='';
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.enable_moves(n:Tsuperregister);
|
||||
procedure trgobj.enable_moves(n:Tsuperregister);
|
||||
|
||||
var m:Tlinkedlistitem;
|
||||
i:cardinal;
|
||||
@ -787,7 +687,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.decrement_degree(m:Tsuperregister);
|
||||
procedure trgobj.decrement_degree(m:Tsuperregister);
|
||||
|
||||
var adj:Pstring;
|
||||
d:byte;
|
||||
@ -826,7 +726,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.simplify;
|
||||
procedure trgobj.simplify;
|
||||
|
||||
var adj:Pstring;
|
||||
i,min,p:byte;
|
||||
@ -873,7 +773,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
function Tregisterallocator.get_alias(n:Tsuperregister):Tsuperregister;
|
||||
function trgobj.get_alias(n:Tsuperregister):Tsuperregister;
|
||||
|
||||
begin
|
||||
while pos(char(n),coalescednodes)<>0 do
|
||||
@ -881,7 +781,7 @@ implementation
|
||||
get_alias:=n;
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.add_worklist(u:Tsuperregister);
|
||||
procedure trgobj.add_worklist(u:Tsuperregister);
|
||||
|
||||
var p:byte;
|
||||
|
||||
@ -900,7 +800,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
function Tregisterallocator.adjacent_ok(u,v:Tsuperregister):boolean;
|
||||
function trgobj.adjacent_ok(u,v:Tsuperregister):boolean;
|
||||
|
||||
{Check wether u and v should be coalesced. u is precoloured.}
|
||||
|
||||
@ -932,7 +832,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
function Tregisterallocator.conservative(u,v:Tsuperregister):boolean;
|
||||
function trgobj.conservative(u,v:Tsuperregister):boolean;
|
||||
|
||||
var adj:Pstring;
|
||||
done:set of char; {To prevent that we count nodes twice.}
|
||||
@ -967,7 +867,7 @@ implementation
|
||||
conservative:=(k<cpu_registers);
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.combine(u,v:Tsuperregister);
|
||||
procedure trgobj.combine(u,v:Tsuperregister);
|
||||
|
||||
var add:boolean;
|
||||
adj:Pstring;
|
||||
@ -1030,7 +930,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.coalesce;
|
||||
procedure trgobj.coalesce;
|
||||
|
||||
var m:Tmoveins;
|
||||
x,y,u,v:Tsuperregister;
|
||||
@ -1081,7 +981,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.freeze_moves(u:Tsuperregister);
|
||||
procedure trgobj.freeze_moves(u:Tsuperregister);
|
||||
|
||||
var i:cardinal;
|
||||
m:Tlinkedlistitem;
|
||||
@ -1119,7 +1019,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.freeze;
|
||||
procedure trgobj.freeze;
|
||||
|
||||
var n:Tsuperregister;
|
||||
|
||||
@ -1133,7 +1033,7 @@ implementation
|
||||
freeze_moves(n);
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.select_spill;
|
||||
procedure trgobj.select_spill;
|
||||
|
||||
var n:char;
|
||||
|
||||
@ -1146,7 +1046,7 @@ implementation
|
||||
freeze_moves(Tsuperregister(n));
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.assign_colours;
|
||||
procedure trgobj.assign_colours;
|
||||
|
||||
{Assign_colours assigns the actual colours to the registers.}
|
||||
|
||||
@ -1215,7 +1115,7 @@ implementation
|
||||
{$endif ra_debug}
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.colour_registers;
|
||||
procedure trgobj.colour_registers;
|
||||
|
||||
begin
|
||||
repeat
|
||||
@ -1234,7 +1134,7 @@ implementation
|
||||
assign_colours;
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.epilogue_colouring;
|
||||
procedure trgobj.epilogue_colouring;
|
||||
|
||||
{
|
||||
procedure move_to_worklist_moves(list:Tlinkedlist);
|
||||
@ -1280,7 +1180,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure Tregisterallocator.clear_interferences(u:Tsuperregister);
|
||||
procedure trgobj.clear_interferences(u:Tsuperregister);
|
||||
|
||||
{Remove node u from the interference graph and remove all collected
|
||||
move instructions it is associated with.}
|
||||
@ -1373,7 +1273,7 @@ implementation
|
||||
{$endif Principle_wrong_by_definition}
|
||||
end;
|
||||
|
||||
procedure Tregisterallocator.getregisterinline(list:Taasmoutput;
|
||||
procedure trgobj.getregisterinline(list:Taasmoutput;
|
||||
position:Tai;subreg:Tsubregister;var result:Tregister);
|
||||
var min,p,i:Tsuperregister;
|
||||
r:Tregister;
|
||||
@ -1461,12 +1361,10 @@ implementation
|
||||
by the normal register get procedures. In other words it is for sure it
|
||||
will never get spilled.}
|
||||
|
||||
function Tregisterallocator.getabtregister(list:Taasmoutput;
|
||||
size:Tcgsize):Tregister;
|
||||
function trgobj.getabtregister(list:Taasmoutput;subreg:tsubregister):Tregister;
|
||||
|
||||
var p,i:Tsuperregister;
|
||||
r:Tregister;
|
||||
subreg:tsubregister;
|
||||
found:boolean;
|
||||
min : byte;
|
||||
adj:Pstring;
|
||||
@ -1528,7 +1426,6 @@ implementation
|
||||
|
||||
exclude(unusedregs,p);
|
||||
include(used_in_proc,p);
|
||||
subreg:=cgsize2subreg(size);
|
||||
r:=newreg(regtype,p,subreg);
|
||||
list.concat(Tai_regalloc.alloc(r));
|
||||
result:=r;
|
||||
@ -1539,7 +1436,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure Tregisterallocator.ungetregisterinline(list:Taasmoutput;
|
||||
procedure trgobj.ungetregisterinline(list:Taasmoutput;
|
||||
position:Tai;r:Tregister);
|
||||
|
||||
var supreg:Tsuperregister;
|
||||
@ -1555,7 +1452,7 @@ implementation
|
||||
add_constraints(r);
|
||||
end;
|
||||
|
||||
function Tregisterallocator.spill_registers(list:Taasmoutput;headertai:tai;const regs_to_spill:string):boolean;
|
||||
function trgobj.spill_registers(list:Taasmoutput;headertai:tai;const regs_to_spill:string):boolean;
|
||||
|
||||
{Returns true if any help registers have been used.}
|
||||
|
||||
@ -1637,386 +1534,18 @@ implementation
|
||||
dispose(spill_temps);
|
||||
end;
|
||||
|
||||
{******************************************************************************
|
||||
Trgobj
|
||||
******************************************************************************}
|
||||
|
||||
constructor Trgobj.create;
|
||||
|
||||
var i:Tsuperregister;
|
||||
|
||||
begin
|
||||
used_in_proc_other:=[];
|
||||
t_times := 0;
|
||||
resetusableregisters;
|
||||
unusedregsfpu:=usableregsfpu;
|
||||
unusedregsmm:=usableregsmm;
|
||||
countunusedregsfpu:=countusableregsfpu;
|
||||
countunusedregsmm:=countusableregsmm;
|
||||
end;
|
||||
|
||||
function trgobj.getregistergenother(list: taasmoutput; const lowreg, highreg: tsuperregister;
|
||||
var unusedregs: tsuperregisterset; var countunusedregs: byte): tregister;
|
||||
var
|
||||
i: tsuperregister;
|
||||
r: Tregister;
|
||||
begin
|
||||
for i:=lowreg to highreg do
|
||||
begin
|
||||
if i in unusedregs then
|
||||
begin
|
||||
exclude(unusedregs,i);
|
||||
include(used_in_proc_other,i);
|
||||
dec(countunusedregs);
|
||||
{$warning Only FPU Registers supported}
|
||||
r:=newreg(R_FPUREGISTER,i,R_SUBNONE);
|
||||
list.concat(tai_regalloc.alloc(r));
|
||||
result := r;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
internalerror(10);
|
||||
end;
|
||||
|
||||
procedure trgobj.ungetregistergen(list: taasmoutput; r: tregister;
|
||||
const usableregs: tsuperregisterset; var unusedregs: tsuperregisterset; var countunusedregs: byte);
|
||||
var
|
||||
supreg : tsuperregister;
|
||||
begin
|
||||
supreg:=getsupreg(r);
|
||||
{ takes much time }
|
||||
if not(supreg in usableregs) then
|
||||
exit;
|
||||
if (supreg in unusedregs) then
|
||||
exit
|
||||
else
|
||||
inc(countunusedregs);
|
||||
include(unusedregs,supreg);
|
||||
list.concat(tai_regalloc.dealloc(r));
|
||||
end;
|
||||
|
||||
{ tries to allocate the passed register, if possible }
|
||||
function trgobj.getexplicitregisterfpu(list : taasmoutput; r : Tregister) : tregister;
|
||||
var
|
||||
supreg : tsuperregister;
|
||||
begin
|
||||
supreg:=getsupreg(r);
|
||||
if supreg in unusedregsfpu then
|
||||
begin
|
||||
dec(countunusedregsfpu);
|
||||
exclude(unusedregsfpu,supreg);
|
||||
include(used_in_proc_other,supreg);
|
||||
list.concat(tai_regalloc.alloc(r));
|
||||
getexplicitregisterfpu:=r;
|
||||
end
|
||||
else
|
||||
{$warning Size for FPU reg is maybe not correct}
|
||||
getexplicitregisterfpu:=getregisterfpu(list,OS_F32);
|
||||
end;
|
||||
|
||||
function trgobj.getregisterfpu(list: taasmoutput;size:Tcgsize) : tregister;
|
||||
|
||||
begin
|
||||
if countunusedregsfpu=0 then
|
||||
internalerror(10);
|
||||
{$warning TODO firstsavefpureg}
|
||||
result := getregistergenother(list,firstsavefpureg,lastsavefpureg,
|
||||
unusedregsfpu,countunusedregsfpu);
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.ungetregisterfpu(list : taasmoutput; r : tregister);
|
||||
|
||||
begin
|
||||
ungetregistergen(list,r,usableregsfpu,unusedregsfpu,
|
||||
countunusedregsfpu);
|
||||
end;
|
||||
|
||||
|
||||
function trgobj.getregistermm(list: taasmoutput) : tregister;
|
||||
begin
|
||||
if countunusedregsmm=0 then
|
||||
internalerror(10);
|
||||
result := getregistergenother(list,firstsavemmreg,lastsavemmreg,
|
||||
unusedregsmm,countunusedregsmm);
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.ungetregistermm(list: taasmoutput; r: tregister);
|
||||
begin
|
||||
ungetregistergen(list,r,usableregsmm,unusedregsmm,
|
||||
countunusedregsmm);
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.ungetregister(list: taasmoutput; r : tregister);
|
||||
|
||||
begin
|
||||
if r=NR_NO then
|
||||
exit;
|
||||
if getregtype(r)=R_FPUREGISTER then
|
||||
ungetregisterfpu(list,r)
|
||||
else if getregtype(r)=R_MMXREGISTER then
|
||||
ungetregistermm(list,r)
|
||||
else internalerror(2002070602);
|
||||
end;
|
||||
|
||||
procedure trgobj.saveotherregvars(list: taasmoutput; const s: totherregisterset);
|
||||
var
|
||||
r: Tregister;
|
||||
begin
|
||||
if not(cs_regvars in aktglobalswitches) then
|
||||
exit;
|
||||
{$warning TODO firstsavefpureg}
|
||||
{
|
||||
if firstsavefpureg <> NR_NO then
|
||||
for r.enum := firstsavefpureg to lastsavefpureg do
|
||||
if is_reg_var_other[r.enum] and
|
||||
(r.enum in s) then
|
||||
store_regvar(list,r);
|
||||
if firstsavemmreg <> R_NO then
|
||||
for r.enum := firstsavemmreg to lastsavemmreg do
|
||||
if is_reg_var_other[r.enum] and
|
||||
(r.enum in s) then
|
||||
store_regvar(list,r);
|
||||
}
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.saveusedotherregisters(list: taasmoutput;
|
||||
var saved : tpushedsavedother; const s: totherregisterset);
|
||||
|
||||
var
|
||||
r : tregister;
|
||||
hr : treference;
|
||||
|
||||
begin
|
||||
used_in_proc_other:=used_in_proc_other + s;
|
||||
|
||||
{$warning TODO firstsavefpureg}
|
||||
(*
|
||||
{ don't try to save the fpu registers if not desired (e.g. for }
|
||||
{ the 80x86) }
|
||||
if firstsavefpureg <> R_NO then
|
||||
for r.enum:=firstsavefpureg to lastsavefpureg do
|
||||
begin
|
||||
saved[r.enum].ofs:=reg_not_saved;
|
||||
{ if the register is used by the calling subroutine and if }
|
||||
{ it's not a regvar (those are handled separately) }
|
||||
if not is_reg_var_other[r.enum] and
|
||||
(r.enum in s) and
|
||||
{ and is present in use }
|
||||
not(r.enum in unusedregsfpu) then
|
||||
begin
|
||||
{ then save it }
|
||||
tg.GetTemp(list,extended_size,tt_persistent,hr);
|
||||
saved[r.enum].ofs:=hr.offset;
|
||||
cg.a_loadfpu_reg_ref(list,OS_FLOAT,r,hr);
|
||||
cg.a_reg_dealloc(list,r);
|
||||
include(unusedregsfpu,r.enum);
|
||||
inc(countunusedregsfpu);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ don't save the vector registers if there's no support for them }
|
||||
if firstsavemmreg <> R_NO then
|
||||
for r.enum:=firstsavemmreg to lastsavemmreg do
|
||||
begin
|
||||
saved[r.enum].ofs:=reg_not_saved;
|
||||
{ if the register is in use and if it's not a regvar (those }
|
||||
{ are handled separately), save it }
|
||||
if not is_reg_var_other[r.enum] and
|
||||
(r.enum in s) and
|
||||
{ and is present in use }
|
||||
not(r.enum in unusedregsmm) then
|
||||
begin
|
||||
{ then save it }
|
||||
tg.GetTemp(list,mmreg_size,tt_persistent,hr);
|
||||
saved[r.enum].ofs:=hr.offset;
|
||||
cg.a_loadmm_reg_ref(list,r,hr);
|
||||
cg.a_reg_dealloc(list,r);
|
||||
include(unusedregsmm,r.enum);
|
||||
inc(countunusedregsmm);
|
||||
end;
|
||||
end;
|
||||
*)
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.restoreusedotherregisters(list : taasmoutput;
|
||||
const saved : tpushedsavedother);
|
||||
|
||||
var
|
||||
r,r2 : tregister;
|
||||
hr : treference;
|
||||
|
||||
begin
|
||||
{$warning TODO firstsavefpureg}
|
||||
(*
|
||||
if firstsavemmreg <> R_NO then
|
||||
for r.enum:=lastsavemmreg downto firstsavemmreg do
|
||||
begin
|
||||
if saved[r.enum].ofs <> reg_not_saved then
|
||||
begin
|
||||
r2.enum:=R_INTREGISTER;
|
||||
r2.number:=NR_FRAME_POINTER_REG;
|
||||
reference_reset_base(hr,r2,saved[r.enum].ofs);
|
||||
cg.a_reg_alloc(list,r);
|
||||
cg.a_loadmm_ref_reg(list,hr,r);
|
||||
if not (r.enum in unusedregsmm) then
|
||||
{ internalerror(10)
|
||||
in n386cal we always save/restore the reg *state*
|
||||
using save/restoreunusedstate -> the current state
|
||||
may not be real (JM) }
|
||||
else
|
||||
begin
|
||||
dec(countunusedregsmm);
|
||||
exclude(unusedregsmm,r.enum);
|
||||
end;
|
||||
tg.UnGetTemp(list,hr);
|
||||
end;
|
||||
end;
|
||||
|
||||
if firstsavefpureg <> R_NO then
|
||||
for r.enum:=lastsavefpureg downto firstsavefpureg do
|
||||
begin
|
||||
if saved[r.enum].ofs <> reg_not_saved then
|
||||
begin
|
||||
r2.enum:=R_INTREGISTER;
|
||||
r2.number:=NR_FRAME_POINTER_REG;
|
||||
reference_reset_base(hr,r2,saved[r.enum].ofs);
|
||||
cg.a_reg_alloc(list,r);
|
||||
cg.a_loadfpu_ref_reg(list,OS_FLOAT,hr,r);
|
||||
if not (r.enum in unusedregsfpu) then
|
||||
{ internalerror(10)
|
||||
in n386cal we always save/restore the reg *state*
|
||||
using save/restoreunusedstate -> the current state
|
||||
may not be real (JM) }
|
||||
else
|
||||
begin
|
||||
dec(countunusedregsfpu);
|
||||
exclude(unusedregsfpu,r.enum);
|
||||
end;
|
||||
tg.UnGetTemp(list,hr);
|
||||
end;
|
||||
end;
|
||||
*)
|
||||
end;
|
||||
|
||||
|
||||
procedure trgobj.resetusableregisters;
|
||||
|
||||
begin
|
||||
{ initialize fields with constant values from cpubase }
|
||||
countusableregsfpu := cpubase.c_countusableregsfpu;
|
||||
countusableregsmm := cpubase.c_countusableregsmm;
|
||||
usableregsfpu := cpubase.usableregsfpu;
|
||||
usableregsmm := cpubase.usableregsmm;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TReference
|
||||
****************************************************************************}
|
||||
|
||||
procedure reference_reset(var ref : treference);
|
||||
begin
|
||||
FillChar(ref,sizeof(treference),0);
|
||||
{$ifdef arm}
|
||||
ref.signindex:=1;
|
||||
{$endif arm}
|
||||
end;
|
||||
|
||||
|
||||
procedure reference_reset_base(var ref : treference;base : tregister;offset : longint);
|
||||
begin
|
||||
reference_reset(ref);
|
||||
ref.base:=base;
|
||||
ref.offset:=offset;
|
||||
end;
|
||||
|
||||
|
||||
procedure reference_reset_symbol(var ref : treference;sym : tasmsymbol;offset : longint);
|
||||
begin
|
||||
reference_reset(ref);
|
||||
ref.symbol:=sym;
|
||||
ref.offset:=offset;
|
||||
end;
|
||||
|
||||
|
||||
procedure reference_release(list: taasmoutput; const ref : treference);
|
||||
begin
|
||||
cg.ungetreference(list,ref);
|
||||
end;
|
||||
|
||||
|
||||
function references_equal(sref : treference;dref : treference):boolean;
|
||||
begin
|
||||
references_equal:=CompareByte(sref,dref,sizeof(treference))=0;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TLocation
|
||||
****************************************************************************}
|
||||
|
||||
procedure location_reset(var l : tlocation;lt:TCGLoc;lsize:TCGSize);
|
||||
begin
|
||||
FillChar(l,sizeof(tlocation),0);
|
||||
l.loc:=lt;
|
||||
l.size:=lsize;
|
||||
{$ifdef arm}
|
||||
if l.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||
l.reference.signindex:=1;
|
||||
{$endif arm}
|
||||
end;
|
||||
|
||||
|
||||
procedure location_release(list: taasmoutput; const l : tlocation);
|
||||
begin
|
||||
case l.loc of
|
||||
LOC_REGISTER,LOC_CREGISTER :
|
||||
begin
|
||||
cg.ungetregister(list,l.register);
|
||||
if l.size in [OS_64,OS_S64] then
|
||||
cg.ungetregister(list,l.registerhigh);
|
||||
end;
|
||||
LOC_FPUREGISTER,LOC_CFPUREGISTER :
|
||||
cg.ungetregister(list,l.register);
|
||||
LOC_CREFERENCE,LOC_REFERENCE :
|
||||
cg.ungetreference(list, l.reference);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure location_freetemp(list:taasmoutput; const l : tlocation);
|
||||
begin
|
||||
if (l.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
||||
tg.ungetiftemp(list,l.reference);
|
||||
end;
|
||||
|
||||
|
||||
procedure location_copy(var destloc:tlocation; const sourceloc : tlocation);
|
||||
begin
|
||||
destloc:=sourceloc;
|
||||
end;
|
||||
|
||||
|
||||
procedure location_swap(var destloc,sourceloc : tlocation);
|
||||
var
|
||||
swapl : tlocation;
|
||||
begin
|
||||
swapl := destloc;
|
||||
destloc := sourceloc;
|
||||
sourceloc := swapl;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.82 2003-10-09 21:31:37 daniel
|
||||
Revision 1.83 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.82 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.81 2003/10/01 20:34:49 peter
|
||||
|
@ -531,8 +531,9 @@ interface
|
||||
{ check the problems of manglednames }
|
||||
has_mangledname : boolean;
|
||||
{ small set which contains the modified registers }
|
||||
usedintregisters:Tsuperregisterset;
|
||||
usedotherregisters:Totherregisterset;
|
||||
usedintregisters,
|
||||
usedmmxregisters,
|
||||
usedfpuregisters : Tsuperregisterset;
|
||||
constructor create(level:byte);
|
||||
constructor ppuload(ppufile:tcompilerppufile);
|
||||
destructor destroy;override;
|
||||
@ -788,8 +789,7 @@ implementation
|
||||
{$endif GDB}
|
||||
fmodule,
|
||||
{ other }
|
||||
gendef,
|
||||
rgobj
|
||||
gendef
|
||||
;
|
||||
|
||||
|
||||
@ -3457,7 +3457,10 @@ implementation
|
||||
lastref:=defref;
|
||||
{ first, we assume that all registers are used }
|
||||
usedintregisters:=paramanager.get_volatile_registers_int(pocall_default);
|
||||
usedotherregisters:=ALL_OTHERREGISTERS;
|
||||
{$ifdef SUPPORT_MMX}
|
||||
usedmmxregisters:=paramanager.get_volatile_registers_fpu(pocall_default);
|
||||
{$endif SUPPORT_MMX}
|
||||
usedfpuregisters:=paramanager.get_volatile_registers_fpu(pocall_default);
|
||||
forwarddef:=true;
|
||||
interfacedef:=false;
|
||||
hasforward:=false;
|
||||
@ -3477,7 +3480,8 @@ implementation
|
||||
deftype:=procdef;
|
||||
|
||||
ppufile.getnormalset(usedintregisters);
|
||||
ppufile.getnormalset(usedotherregisters);
|
||||
ppufile.getnormalset(usedfpuregisters);
|
||||
{$warning need to add usedmmxregisters}
|
||||
has_mangledname:=boolean(ppufile.getbyte);
|
||||
if has_mangledname then
|
||||
_mangledname:=stringdup(ppufile.getstring)
|
||||
@ -3603,11 +3607,13 @@ implementation
|
||||
if simplify_ppu then
|
||||
begin
|
||||
usedintregisters:=paramanager.get_volatile_registers_int(pocall_default);
|
||||
usedotherregisters:=ALL_OTHERREGISTERS;
|
||||
usedfpuregisters:=paramanager.get_volatile_registers_fpu(pocall_default);
|
||||
usedmmxregisters:=paramanager.get_volatile_registers_mmx(pocall_default);
|
||||
end;
|
||||
|
||||
ppufile.putnormalset(usedintregisters);
|
||||
ppufile.putnormalset(usedotherregisters);
|
||||
ppufile.putnormalset(usedfpuregisters);
|
||||
{$warning need to add usedmmxregisters}
|
||||
ppufile.do_interface_crc:=oldintfcrc;
|
||||
ppufile.putbyte(byte(has_mangledname));
|
||||
if has_mangledname then
|
||||
@ -5918,7 +5924,14 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.175 2003-10-07 20:43:49 peter
|
||||
Revision 1.176 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.175 2003/10/07 20:43:49 peter
|
||||
* Add calling convention in fullprocname when it is specified
|
||||
|
||||
Revision 1.174 2003/10/07 16:06:30 peter
|
||||
|
@ -40,7 +40,7 @@ interface
|
||||
{$ifdef GDB}
|
||||
gdb,
|
||||
{$endif}
|
||||
import,export,link,rgobj,i_win32;
|
||||
import,export,link,cgobj,i_win32;
|
||||
|
||||
|
||||
const
|
||||
@ -1622,7 +1622,14 @@ initialization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.22 2003-10-09 16:14:49 peter
|
||||
Revision 1.23 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.22 2003/10/09 16:14:49 peter
|
||||
* fix check for generatenasmlib
|
||||
|
||||
Revision 1.21 2003/10/03 14:16:48 marco
|
||||
|
@ -59,8 +59,8 @@ implementation
|
||||
|
||||
uses
|
||||
cutils,
|
||||
systems,globals,verbose,
|
||||
cgobj,tgobj,rgobj;
|
||||
systems,verbose,
|
||||
cgobj;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
@ -161,7 +161,14 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.6 2003-10-09 21:31:37 daniel
|
||||
Revision 1.7 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.6 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.5 2003/10/01 20:34:50 peter
|
||||
|
@ -36,14 +36,16 @@ unit cgx86;
|
||||
|
||||
type
|
||||
tcgx86 = class(tcg)
|
||||
rgint : Tregisterallocatorcpu;
|
||||
rgother : Trgcpu;
|
||||
rgint,
|
||||
rgmmx : trgcpu;
|
||||
rgfpu : Trgx86fpu;
|
||||
procedure init_register_allocators;override;
|
||||
procedure done_register_allocators;override;
|
||||
|
||||
function getintregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||
function getaddressregister(list:Taasmoutput):Tregister;override;
|
||||
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||
function getmmxregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||
procedure getexplicitregister(list:Taasmoutput;r:Tregister);override;
|
||||
function getabtregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||
procedure ungetregister(list:Taasmoutput;r:Tregister);override;
|
||||
@ -174,42 +176,52 @@ unit cgx86;
|
||||
|
||||
|
||||
procedure Tcgx86.init_register_allocators;
|
||||
begin
|
||||
rgint:=trgcpu.create(6,R_INTREGISTER,R_SUBWHOLE,#0#1#2#3#4#5,first_int_imreg,[RS_EBP]);
|
||||
rgmmx:=trgcpu.create(8,R_MMXREGISTER,R_SUBNONE,#0#1#2#3#4#5#6#7,first_mmx_imreg,[]);
|
||||
rgfpu:=Trgx86fpu.create;
|
||||
end;
|
||||
|
||||
begin
|
||||
rgint:=Tregisterallocatorcpu.create(6,R_INTREGISTER,#0#1#2#3#4#5,first_int_imreg,[RS_EBP]);
|
||||
rgother:=Trgcpu.create;
|
||||
end;
|
||||
|
||||
procedure Tcgx86.done_register_allocators;
|
||||
begin
|
||||
rgint.free;
|
||||
rgmmx.free;
|
||||
rgfpu.free;
|
||||
end;
|
||||
|
||||
begin
|
||||
rgint.free;
|
||||
rgother.free;
|
||||
end;
|
||||
|
||||
function Tcgx86.getintregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
result:=rgint.getregister(list,cgsize2subreg(size));
|
||||
end;
|
||||
|
||||
begin
|
||||
getintregister:=rgint.getregister(list,size);
|
||||
end;
|
||||
|
||||
function Tcgx86.getaddressregister(list:Taasmoutput):Tregister;
|
||||
begin
|
||||
result:=rgint.getregister(list,R_SUBWHOLE);
|
||||
end;
|
||||
|
||||
begin
|
||||
getaddressregister:=rgint.getregister(list,OS_INT);
|
||||
end;
|
||||
|
||||
function Tcgx86.getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
result:=rgfpu.getregisterfpu(list);
|
||||
end;
|
||||
|
||||
|
||||
function Tcgx86.getmmxregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
result:=rgmmx.getregister(list,R_SUBNONE);
|
||||
end;
|
||||
|
||||
begin
|
||||
getfpuregister:=rgother.getregisterfpu(list,size);
|
||||
end;
|
||||
|
||||
procedure Tcgx86.getexplicitregister(list:Taasmoutput;r:Tregister);
|
||||
begin
|
||||
case getregtype(r) of
|
||||
R_INTREGISTER :
|
||||
rgint.getexplicitregister(list,r);
|
||||
R_MMXREGISTER :
|
||||
rgmmx.getexplicitregister(list,r);
|
||||
else
|
||||
internalerror(200310091);
|
||||
end;
|
||||
@ -218,7 +230,7 @@ unit cgx86;
|
||||
|
||||
function tcgx86.getabtregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
result:=rgint.getabtregister(list,size);
|
||||
result:=rgint.getabtregister(list,cgsize2subreg(size));
|
||||
end;
|
||||
|
||||
|
||||
@ -228,7 +240,9 @@ unit cgx86;
|
||||
R_INTREGISTER :
|
||||
rgint.ungetregister(list,r);
|
||||
R_FPUREGISTER :
|
||||
rgother.ungetregisterfpu(list,r);
|
||||
rgfpu.ungetregisterfpu(list,r);
|
||||
R_MMXREGISTER :
|
||||
rgmmx.ungetregister(list,r);
|
||||
else
|
||||
internalerror(200310091);
|
||||
end;
|
||||
@ -249,6 +263,8 @@ unit cgx86;
|
||||
case rt of
|
||||
R_INTREGISTER :
|
||||
rgint.allocexplicitregisters(list,r);
|
||||
R_MMXREGISTER :
|
||||
rgmmx.allocexplicitregisters(list,r);
|
||||
else
|
||||
internalerror(200310092);
|
||||
end;
|
||||
@ -260,6 +276,8 @@ unit cgx86;
|
||||
case rt of
|
||||
R_INTREGISTER :
|
||||
rgint.deallocexplicitregisters(list,r);
|
||||
R_MMXREGISTER :
|
||||
rgmmx.deallocexplicitregisters(list,r);
|
||||
else
|
||||
internalerror(200310093);
|
||||
end;
|
||||
@ -274,21 +292,25 @@ unit cgx86;
|
||||
|
||||
procedure tcgx86.dec_fpu_stack;
|
||||
begin
|
||||
dec(rgother.fpuvaroffset);
|
||||
dec(rgfpu.fpuvaroffset);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgx86.inc_fpu_stack;
|
||||
begin
|
||||
inc(rgother.fpuvaroffset);
|
||||
inc(rgfpu.fpuvaroffset);
|
||||
end;
|
||||
|
||||
|
||||
procedure Tcgx86.do_register_allocation(list:Taasmoutput;headertai:tai);
|
||||
|
||||
begin
|
||||
{ Int }
|
||||
rgint.do_register_allocation(list,headertai);
|
||||
list.translate_registers(rgint.colour);
|
||||
list.translate_registers(R_INTREGISTER,rgint.colour);
|
||||
{ MMX }
|
||||
rgmmx.do_register_allocation(list,headertai);
|
||||
list.translate_registers(R_MMXREGISTER,rgmmx.colour);
|
||||
end;
|
||||
|
||||
|
||||
@ -708,12 +730,12 @@ unit cgx86;
|
||||
begin
|
||||
if (reg1<>NR_ST) then
|
||||
begin
|
||||
list.concat(taicpu.op_reg(A_FLD,S_NO,rgother.correct_fpuregister(reg1,rgother.fpuvaroffset)));
|
||||
list.concat(taicpu.op_reg(A_FLD,S_NO,rgfpu.correct_fpuregister(reg1,rgfpu.fpuvaroffset)));
|
||||
inc_fpu_stack;
|
||||
end;
|
||||
if (reg2<>NR_ST) then
|
||||
begin
|
||||
list.concat(taicpu.op_reg(A_FSTP,S_NO,rgother.correct_fpuregister(reg2,rgother.fpuvaroffset)));
|
||||
list.concat(taicpu.op_reg(A_FSTP,S_NO,rgfpu.correct_fpuregister(reg2,rgfpu.fpuvaroffset)));
|
||||
dec_fpu_stack;
|
||||
end;
|
||||
end;
|
||||
@ -1713,7 +1735,14 @@ unit cgx86;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.75 2003-10-09 21:31:37 daniel
|
||||
Revision 1.76 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.75 2003/10/09 21:31:37 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.74 2003/10/07 16:09:03 florian
|
||||
|
@ -58,12 +58,12 @@ interface
|
||||
implementation
|
||||
|
||||
uses
|
||||
verbose,systems,globtype,globals,
|
||||
symconst,symdef,aasmbase,aasmtai,aasmcpu,
|
||||
verbose,systems,globals,
|
||||
aasmbase,aasmtai,
|
||||
cgbase,pass_2,
|
||||
ncon,ncal,ncnv,
|
||||
cpubase,
|
||||
cgobj,tgobj,rgobj,ncgutil;
|
||||
cgobj,ncgutil;
|
||||
|
||||
|
||||
procedure tx86typeconvnode.second_int_to_bool;
|
||||
@ -166,7 +166,14 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.6 2003-10-09 21:31:38 daniel
|
||||
Revision 1.7 2003-10-10 17:48:14 peter
|
||||
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
|
||||
* tregisteralloctor renamed to trgobj
|
||||
* removed rgobj from a lot of units
|
||||
* moved location_* and reference_* to cgobj
|
||||
* first things for mmx register allocation
|
||||
|
||||
Revision 1.6 2003/10/09 21:31:38 daniel
|
||||
* Register allocator splitted, ans abstract now
|
||||
|
||||
Revision 1.5 2003/10/01 20:34:51 peter
|
||||
|
Loading…
Reference in New Issue
Block a user