* passing a var parameter to var parameter is now also allowed

for register locations (=regvars)
This commit is contained in:
peter 2004-10-10 20:21:18 +00:00
parent 1badf97d89
commit 0573c742e4
2 changed files with 60 additions and 45 deletions

View File

@ -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

View File

@ -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