* (de)allocation of registers for parameters is now performed properly

(and checked on the ppc)
  - removed obsolete allocation of all parameter registers at the start
    of a procedure (and deallocation at the end)
This commit is contained in:
Jonas Maebe 2003-06-09 14:54:26 +00:00
parent c8978e3440
commit 55509b199b
6 changed files with 172 additions and 47 deletions

View File

@ -132,6 +132,8 @@ implementation
objectlibrary.getlabel(truelabel);
objectlibrary.getlabel(falselabel);
secondpass(left);
{ allocate paraloc }
paramanager.allocparaloc(exprasmlist,paraitem.paraloc);
{ handle varargs first, because defcoll is not valid }
if (nf_varargs_para in flags) then
begin
@ -918,6 +920,9 @@ implementation
{$endif newra}
end;
{ free the resources allocated for the parameters }
paramanager.freeparalocs(exprasmlist,tparaitem(procdefinition.para.first));
{ Need to remove the parameters from the stack? }
if (po_clearstack in procdefinition.procoptions) then
begin
@ -1407,7 +1412,13 @@ begin
end.
{
$Log$
Revision 1.89 2003-06-09 12:23:29 peter
Revision 1.90 2003-06-09 14:54:26 jonas
* (de)allocation of registers for parameters is now performed properly
(and checked on the ppc)
- removed obsolete allocation of all parameter registers at the start
of a procedure (and deallocation at the end)
Revision 1.89 2003/06/09 12:23:29 peter
* init/final of procedure data splitted from genentrycode
* use asmnode getposition to insert final at the correct position
als for the implicit try...finally

View File

@ -75,10 +75,34 @@ unit paramgr;
{# frees a parameter location allocated with getintparaloc
@param(list Current assembler list)
@param(nr Parameter numver of routine, starting from 1)
@param(nr Parameter number of routine, starting from 1)
}
procedure freeintparaloc(list: taasmoutput; nr : longint); virtual;
{# allocate a parameter location created with create_param_loc_info
@param(list Current assembler list)
@param(loc Parameter location)
}
procedure allocparaloc(list: taasmoutput; const loc: tparalocation); virtual;
{# free a parameter location allocated with allocparaloc
@param(list Current assembler list)
@param(loc Parameter location)
}
procedure freeparaloc(list: taasmoutput; const loc: tparalocation); virtual;
{# free all parameters allocated with allocparaloc for a procedure
@param(list Current assembler list)
@param(paraitem First paraitem of the procedure)
}
procedure freeparalocs(list: taasmoutput; paraitem: tparaitem);
{# This is used to populate the location information on all parameters
for the routine. This is used for normal call resolution.
}
@ -253,6 +277,46 @@ unit paramgr;
end;
procedure tparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation);
begin
case loc.loc of
LOC_REGISTER, LOC_CREGISTER:
rg.getexplicitregisterint(list,loc.register.number);
LOC_FPUREGISTER, LOC_CFPUREGISTER:
rg.getexplicitregisterfpu(list,loc.register.enum);
LOC_REFERENCE,LOC_CREFERENCE:
{ do nothing by default, most of the time it's the framepointer }
else
internalerror(200306091);
end;
end;
procedure tparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
begin
case loc.loc of
LOC_REGISTER, LOC_CREGISTER:
rg.ungetregisterint(list,loc.register);
LOC_FPUREGISTER, LOC_CFPUREGISTER:
rg.ungetregisterfpu(list,loc.register);
LOC_REFERENCE,LOC_CREFERENCE:
{ do nothing by default, most of the time it's the framepointer }
else
internalerror(200306091);
end;
end;
procedure tparamanager.freeparalocs(list: taasmoutput; paraitem: tparaitem);
begin
while assigned(paraitem) do
begin
freeparaloc(list,paraitem.paraloc);
paraitem := tparaitem(paraitem.next);
end;
end;
function tparamanager.getfuncretparaloc(p : tabstractprocdef) : tparalocation;
begin
result.loc:=LOC_REFERENCE;
@ -395,7 +459,13 @@ end.
{
$Log$
Revision 1.42 2003-06-08 10:54:41 jonas
Revision 1.43 2003-06-09 14:54:26 jonas
* (de)allocation of registers for parameters is now performed properly
(and checked on the ppc)
- removed obsolete allocation of all parameter registers at the start
of a procedure (and deallocation at the end)
Revision 1.42 2003/06/08 10:54:41 jonas
- disabled changing of LOC_*REGISTER to LOC_C*REGISTER in setparalocs,
this is not necessary anymore (doesn't do anything anymore actually,
except making sure the interface crc changes)

View File

@ -993,13 +993,6 @@ const
r.number:=NR_R11;
a_reg_alloc(list,r);
end;
{ allocate registers containing reg parameters }
r.enum := R_INTREGISTER;
for regcounter2 := RS_R3 to RS_R10 do
begin
r.number:=regcounter2 shl 8;
a_reg_alloc(list,r);
end;
usesfpr:=false;
@ -1227,13 +1220,6 @@ const
begin
localsize := 0;
{ release parameter registers }
r.enum := R_INTREGISTER;
for regcounter2 := RS_R3 to RS_R10 do
begin
r.number:=regcounter2 shl 8;
a_reg_dealloc(list,r);
end;
{ AltiVec context restore, not yet implemented !!! }
usesfpr:=false;
@ -1545,16 +1531,6 @@ const
a_reg_alloc(list,rsp);
a_reg_alloc(list,r);
{ allocate registers containing reg parameters }
r.enum := R_INTREGISTER;
for regcounter2 := RS_R3 to RS_R10 do
begin
r.number:=regcounter2 shl 8;
a_reg_alloc(list,r);
end;
{TODO: Allocate fp and altivec parameter registers also}
{ save return address in callers frame}
r2.enum:=R_LR;
list.concat(taicpu.op_reg_reg(A_MFSPR,r,r2));
@ -1628,15 +1604,6 @@ const
r,r2,rsp:Tregister;
regcounter2: Tsuperregister;
begin
{ release parameter registers }
r.enum := R_INTREGISTER;
for regcounter2 := RS_R3 to RS_R10 do
begin
r.number := regcounter2 shl 8;
a_reg_dealloc(list,r);
end;
{TODO: Release fp and altivec parameter registers also}
r.enum:=R_INTREGISTER;
r.number:=NR_R0;
rsp.enum:=R_INTREGISTER;
@ -2565,7 +2532,13 @@ begin
end.
{
$Log$
Revision 1.106 2003-06-08 18:19:27 jonas
Revision 1.107 2003-06-09 14:54:26 jonas
* (de)allocation of registers for parameters is now performed properly
(and checked on the ppc)
- removed obsolete allocation of all parameter registers at the start
of a procedure (and deallocation at the end)
Revision 1.106 2003/06/08 18:19:27 jonas
- removed duplicate identifier
Revision 1.105 2003/06/07 18:57:04 jonas

View File

@ -38,6 +38,8 @@ unit cpupara;
function push_addr_param(def : tdef;calloption : tproccalloption) : boolean;override;
function getintparaloc(list: taasmoutput; nr : longint) : tparalocation;override;
procedure freeintparaloc(list: taasmoutput; nr : longint); override;
procedure allocparaloc(list: taasmoutput; const loc: tparalocation);
procedure freeparaloc(list: taasmoutput; const loc: tparalocation);
procedure create_param_loc_info(p : tabstractprocdef);override;
function getfuncretparaloc(p : tabstractprocdef) : tparalocation;override;
end;
@ -90,6 +92,25 @@ unit cpupara;
end;
end;
procedure tppcparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation);
begin
if (loc.size in [OS_64,OS_S64]) and
(loc.loc in [LOC_REGISTER,LOC_CREGISTER]) then
rg.getexplicitregisterint(list,loc.registerhigh.number);
inherited allocparaloc(list,loc);
end;
procedure tppcparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
begin
if (loc.size in [OS_64,OS_S64]) and
(loc.loc in [LOC_REGISTER,LOC_CREGISTER]) then
rg.ungetregisterint(list,loc.registerhigh);
inherited allocparaloc(list,loc);
end;
function getparaloc(p : tdef) : tcgloc;
begin
@ -364,7 +385,13 @@ begin
end.
{
$Log$
Revision 1.36 2003-06-08 10:52:01 jonas
Revision 1.37 2003-06-09 14:54:26 jonas
* (de)allocation of registers for parameters is now performed properly
(and checked on the ppc)
- removed obsolete allocation of all parameter registers at the start
of a procedure (and deallocation at the end)
Revision 1.36 2003/06/08 10:52:01 jonas
* zero paraloc tregisters, so that the alignment bytes are 0 (otherwise
the crc of the ppu files can change between interface and
implementation)

View File

@ -37,6 +37,8 @@ unit rgcpu;
trgcpu = class(trgobj)
function getexplicitregisterint(list: taasmoutput; reg: Tnewregister): tregister; override;
procedure ungetregisterint(list: taasmoutput; reg: tregister); override;
function getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;override;
procedure ungetregisterfpu(list: taasmoutput; r : tregister);override;
procedure saveusedintregisters(list:Taasmoutput;
var saved:Tpushedsavedint;
const s:Tsupregset);override;
@ -46,6 +48,7 @@ unit rgcpu;
procedure cleartempgen; override;
private
usedpararegs: Tsupregset;
usedparafpuregs: tregisterset;
end;
implementation
@ -55,8 +58,6 @@ unit rgcpu;
function trgcpu.getexplicitregisterint(list: taasmoutput; reg: Tnewregister): tregister;
var r:Tregister;
begin
if ((reg shr 8) in [RS_R0,RS_R2..RS_R12]) and
not((reg shr 8) in is_reg_var_int) then
@ -64,10 +65,9 @@ unit rgcpu;
if (reg shr 8) in usedpararegs then
internalerror(2003060701);
include(usedpararegs,reg shr 8);
r.enum:=R_INTREGISTER;
r.number:=reg;
cg.a_reg_alloc(list,r);
result := r;
result.enum:=R_INTREGISTER;
result.number:=reg;
cg.a_reg_alloc(list,result);
end
else result := inherited getexplicitregisterint(list,reg);
end;
@ -89,6 +89,37 @@ unit rgcpu;
end;
function trgcpu.getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;
begin
if (r in [R_F1..R_F13]) and
not is_reg_var_other[r] then
begin
if r in usedparafpuregs then
internalerror(2003060902);
include(usedparafpuregs,r);
result.enum := r;
cg.a_reg_alloc(list,result);
end
else
result := inherited getexplicitregisterfpu(list,r);
end;
procedure trgcpu.ungetregisterfpu(list: taasmoutput; r : tregister);
begin
if (r.enum in [R_F1..R_F13]) and
not is_reg_var_other[r.enum] then
begin
if not(r.enum in usedparafpuregs) then
internalerror(2003060903);
exclude(usedparafpuregs,r.enum);
cg.a_reg_dealloc(list,r);
end
else
inherited ungetregisterfpu(list,r);
end;
procedure trgcpu.saveusedintregisters(list:Taasmoutput;
var saved:Tpushedsavedint;
const s:Tsupregset);
@ -116,6 +147,7 @@ unit rgcpu;
begin
inherited cleartempgen;
usedpararegs := [];
usedparafpuregs := [];
end;
initialization
@ -124,7 +156,13 @@ end.
{
$Log$
Revision 1.8 2003-06-07 18:57:04 jonas
Revision 1.9 2003-06-09 14:54:26 jonas
* (de)allocation of registers for parameters is now performed properly
(and checked on the ppc)
- removed obsolete allocation of all parameter registers at the start
of a procedure (and deallocation at the end)
Revision 1.8 2003/06/07 18:57:04 jonas
+ added freeintparaloc
* ppc get/freeintparaloc now check whether the parameter regs are
properly allocated/deallocated (and get an extra list para)

View File

@ -280,7 +280,7 @@ unit rgobj;
@param(r specific register to allocate)
}
function getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;
function getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;virtual;
{# Deallocate any kind of register }
procedure ungetregister(list: taasmoutput; r : tregister); virtual;
@ -2463,7 +2463,13 @@ end.
{
$Log$
Revision 1.50 2003-06-03 21:11:09 peter
Revision 1.51 2003-06-09 14:54:26 jonas
* (de)allocation of registers for parameters is now performed properly
(and checked on the ppc)
- removed obsolete allocation of all parameter registers at the start
of a procedure (and deallocation at the end)
Revision 1.50 2003/06/03 21:11:09 peter
* cg.a_load_* get a from and to size specifier
* makeregsize only accepts newregister
* i386 uses generic tcgnotnode,tcgunaryminus