mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-17 12:59:24 +02:00
* (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:
parent
c8978e3440
commit
55509b199b
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user