mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 04:39:34 +02:00
* passing a var parameter to var parameter is now also allowed
for register locations (=regvars)
This commit is contained in:
parent
1badf97d89
commit
0573c742e4
@ -428,20 +428,33 @@ implementation
|
|||||||
paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,
|
paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,
|
||||||
aktcallnode.procdefinition.proccalloption)) then
|
aktcallnode.procdefinition.proccalloption)) then
|
||||||
begin
|
begin
|
||||||
{ Check for passing a constant to var,out parameter }
|
{ Passing a var parameter to a var parameter, we can
|
||||||
if (paraitem.paratyp in [vs_var,vs_out]) and
|
just push the address transparently }
|
||||||
(left.location.loc<>LOC_REFERENCE) then
|
if (left.nodetype=loadn) and
|
||||||
begin
|
(tloadnode(left).is_addr_param_load) then
|
||||||
{ passing self to a var parameter is allowed in
|
begin
|
||||||
TP and delphi }
|
if (left.location.reference.index<>NR_NO) or
|
||||||
if not((left.location.loc=LOC_CREFERENCE) and
|
(left.location.reference.offset<>0) then
|
||||||
is_self_node(left)) then
|
internalerror(200410107);
|
||||||
internalerror(200106041);
|
cg.a_param_reg(exprasmlist,OS_ADDR,left.location.reference.base,tempcgpara)
|
||||||
end;
|
end
|
||||||
{ Force to be in memory }
|
else
|
||||||
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
begin
|
||||||
location_force_mem(exprasmlist,left.location);
|
{ Check for passing a constant to var,out parameter }
|
||||||
push_addr_para;
|
if (paraitem.paratyp in [vs_var,vs_out]) and
|
||||||
|
(left.location.loc<>LOC_REFERENCE) then
|
||||||
|
begin
|
||||||
|
{ passing self to a var parameter is allowed in
|
||||||
|
TP and delphi }
|
||||||
|
if not((left.location.loc=LOC_CREFERENCE) and
|
||||||
|
is_self_node(left)) then
|
||||||
|
internalerror(200106041);
|
||||||
|
end;
|
||||||
|
{ Force to be in memory }
|
||||||
|
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
||||||
|
location_force_mem(exprasmlist,left.location);
|
||||||
|
push_addr_para;
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
push_value_para;
|
push_value_para;
|
||||||
@ -1049,8 +1062,7 @@ implementation
|
|||||||
{ Allocate parameters and locals }
|
{ Allocate parameters and locals }
|
||||||
gen_alloc_inline_parast(exprasmlist,tprocdef(procdefinition));
|
gen_alloc_inline_parast(exprasmlist,tprocdef(procdefinition));
|
||||||
gen_alloc_inline_funcret(exprasmlist,tprocdef(procdefinition));
|
gen_alloc_inline_funcret(exprasmlist,tprocdef(procdefinition));
|
||||||
if tprocdef(procdefinition).localst.symtabletype=localsymtable then
|
gen_alloc_symtable(exprasmlist,tlocalsymtable(tprocdef(procdefinition).localst));
|
||||||
gen_alloc_localst(exprasmlist,tlocalsymtable(tprocdef(procdefinition).localst));
|
|
||||||
|
|
||||||
{ if we allocate the temp. location for ansi- or widestrings }
|
{ if we allocate the temp. location for ansi- or widestrings }
|
||||||
{ already here, we avoid later a push/pop }
|
{ already here, we avoid later a push/pop }
|
||||||
@ -1183,9 +1195,8 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{ Release parameters and locals }
|
{ Release parameters and locals }
|
||||||
gen_free_parast(exprasmlist,tparasymtable(current_procinfo.procdef.parast));
|
gen_free_symtable(exprasmlist,tparasymtable(current_procinfo.procdef.parast));
|
||||||
if current_procinfo.procdef.localst.symtabletype=localsymtable then
|
gen_free_symtable(exprasmlist,tlocalsymtable(current_procinfo.procdef.localst));
|
||||||
gen_free_localst(exprasmlist,tlocalsymtable(current_procinfo.procdef.localst));
|
|
||||||
|
|
||||||
{$ifdef GDB}
|
{$ifdef GDB}
|
||||||
if (cs_debuginfo in aktmoduleswitches) and
|
if (cs_debuginfo in aktmoduleswitches) and
|
||||||
@ -1232,7 +1243,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.176 2004-09-27 15:15:20 peter
|
Revision 1.177 2004-10-10 20:21:18 peter
|
||||||
|
* passing a var parameter to var parameter is now also allowed
|
||||||
|
for register locations (=regvars)
|
||||||
|
|
||||||
|
Revision 1.176 2004/09/27 15:15:20 peter
|
||||||
* dealloc function result registers, register allocation is now
|
* dealloc function result registers, register allocation is now
|
||||||
back at pre-paraloc level
|
back at pre-paraloc level
|
||||||
|
|
||||||
|
@ -119,13 +119,8 @@ implementation
|
|||||||
begin
|
begin
|
||||||
symtabletype:=symtable.symtabletype;
|
symtabletype:=symtable.symtabletype;
|
||||||
hregister:=NR_NO;
|
hregister:=NR_NO;
|
||||||
{ C variable }
|
|
||||||
if (vo_is_C_var in tvarsym(symtableentry).varoptions) then
|
|
||||||
begin
|
|
||||||
location.reference.symbol:=objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA);
|
|
||||||
end
|
|
||||||
{ DLL variable }
|
{ DLL variable }
|
||||||
else if (vo_is_dll_var in tvarsym(symtableentry).varoptions) then
|
if (vo_is_dll_var in tvarsym(symtableentry).varoptions) then
|
||||||
begin
|
begin
|
||||||
if target_info.system=system_powerpc_darwin then
|
if target_info.system=system_powerpc_darwin then
|
||||||
begin
|
begin
|
||||||
@ -141,12 +136,7 @@ implementation
|
|||||||
reference_reset_base(location.reference,hregister,0);
|
reference_reset_base(location.reference,hregister,0);
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
{ external variable }
|
{ Thread variable }
|
||||||
else if (vo_is_external in tvarsym(symtableentry).varoptions) then
|
|
||||||
begin
|
|
||||||
location.reference.symbol:=objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA);
|
|
||||||
end
|
|
||||||
{ thread variable }
|
|
||||||
else if (vo_is_thread_var in tvarsym(symtableentry).varoptions) then
|
else if (vo_is_thread_var in tvarsym(symtableentry).varoptions) then
|
||||||
begin
|
begin
|
||||||
{
|
{
|
||||||
@ -192,7 +182,7 @@ implementation
|
|||||||
cg.a_label(exprasmlist,endrelocatelab);
|
cg.a_label(exprasmlist,endrelocatelab);
|
||||||
location.reference.base:=hregister;
|
location.reference.base:=hregister;
|
||||||
end
|
end
|
||||||
{ nested variable }
|
{ Nested variable }
|
||||||
else if assigned(left) then
|
else if assigned(left) then
|
||||||
begin
|
begin
|
||||||
if not(symtabletype in [localsymtable,parasymtable]) then
|
if not(symtabletype in [localsymtable,parasymtable]) then
|
||||||
@ -205,7 +195,7 @@ implementation
|
|||||||
hregister:=left.location.register;
|
hregister:=left.location.register;
|
||||||
reference_reset_base(location.reference,hregister,tvarsym(symtableentry).localloc.reference.offset);
|
reference_reset_base(location.reference,hregister,tvarsym(symtableentry).localloc.reference.offset);
|
||||||
end
|
end
|
||||||
{ normal variable }
|
{ Normal (or external) variable }
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
{$ifdef OLDREGVARS}
|
{$ifdef OLDREGVARS}
|
||||||
@ -246,7 +236,12 @@ implementation
|
|||||||
internalerror(200403023);
|
internalerror(200403023);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
location.reference.symbol:=objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA);
|
begin
|
||||||
|
if tvarsym(symtableentry).localloc.loc=LOC_INVALID then
|
||||||
|
reference_reset_symbol(location.reference,objectlibrary.newasmsymbol(tvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA),0)
|
||||||
|
else
|
||||||
|
location:=tvarsym(symtableentry).localloc;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
internalerror(200305102);
|
internalerror(200305102);
|
||||||
@ -257,16 +252,17 @@ implementation
|
|||||||
{ handle call by reference variables when they are not
|
{ handle call by reference variables when they are not
|
||||||
alreayd copied to local copies. Also ignore the reference
|
alreayd copied to local copies. Also ignore the reference
|
||||||
when we need to load the self pointer for objects }
|
when we need to load the self pointer for objects }
|
||||||
if (symtabletype=parasymtable) and
|
if is_addr_param_load then
|
||||||
not(vo_has_local_copy in tvarsym(symtableentry).varoptions) and
|
|
||||||
not(nf_load_self_pointer in flags) and
|
|
||||||
paramanager.push_addr_param(tvarsym(symtableentry).varspez,tvarsym(symtableentry).vartype.def,tprocdef(symtable.defowner).proccalloption) then
|
|
||||||
begin
|
begin
|
||||||
if hregister=NR_NO then
|
if (location.loc in [LOC_CREGISTER,LOC_REGISTER]) then
|
||||||
hregister:=cg.getaddressregister(exprasmlist);
|
hregister:=location.register
|
||||||
{ we need to load only an address }
|
else
|
||||||
location.size:=OS_ADDR;
|
begin
|
||||||
cg.a_load_loc_reg(exprasmlist,location.size,location,hregister);
|
hregister:=cg.getaddressregister(exprasmlist);
|
||||||
|
{ we need to load only an address }
|
||||||
|
location.size:=OS_ADDR;
|
||||||
|
cg.a_load_loc_reg(exprasmlist,location.size,location,hregister);
|
||||||
|
end;
|
||||||
location_reset(location,LOC_REFERENCE,newsize);
|
location_reset(location,LOC_REFERENCE,newsize);
|
||||||
location.reference.base:=hregister;
|
location.reference.base:=hregister;
|
||||||
end;
|
end;
|
||||||
@ -927,7 +923,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.126 2004-09-26 17:45:30 peter
|
Revision 1.127 2004-10-10 20:21:18 peter
|
||||||
|
* passing a var parameter to var parameter is now also allowed
|
||||||
|
for register locations (=regvars)
|
||||||
|
|
||||||
|
Revision 1.126 2004/09/26 17:45:30 peter
|
||||||
* simple regvar support, not yet finished
|
* simple regvar support, not yet finished
|
||||||
|
|
||||||
Revision 1.125 2004/09/25 14:23:54 peter
|
Revision 1.125 2004/09/25 14:23:54 peter
|
||||||
|
Loading…
Reference in New Issue
Block a user