mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-09 21:49:18 +02:00
* symtable allocation rewritten
* loading of parameters to local temps/regs cleanup * regvar support for parameters * regvar support for staticsymtable (main body)
This commit is contained in:
parent
0573c742e4
commit
b0c25b50a0
@ -189,11 +189,6 @@ unit cgobj;
|
||||
second the destination
|
||||
}
|
||||
|
||||
{ Copy a parameter to a (temporary) reference }
|
||||
procedure a_loadany_param_ref(list : taasmoutput;const paraloc : TCGPara;const ref:treference;shuffle : pmmshuffle);virtual;
|
||||
{ Copy a parameter to a register }
|
||||
procedure a_loadany_param_reg(list : taasmoutput;const paraloc : TCGPara;const reg:tregister;shuffle : pmmshuffle);virtual;
|
||||
|
||||
{# Emits instruction to call the method specified by symbol name.
|
||||
This routine must be overriden for each new target cpu.
|
||||
|
||||
@ -838,116 +833,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg.a_loadany_param_ref(list : taasmoutput;const paraloc : TCGPara;const ref:treference;shuffle : pmmshuffle);
|
||||
|
||||
procedure gen_load(paraloc:TCGParaLocation;const ref:treference);
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
case paraloc.loc of
|
||||
LOC_CREGISTER,
|
||||
LOC_REGISTER:
|
||||
begin
|
||||
if getsupreg(paraloc.register)<first_int_imreg then
|
||||
begin
|
||||
getcpuregister(list,paraloc.register);
|
||||
ungetcpuregister(list,paraloc.register);
|
||||
end;
|
||||
a_load_reg_ref(list,paraloc.size,paraloc.size,paraloc.register,ref);
|
||||
end;
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER:
|
||||
begin
|
||||
if getsupreg(paraloc.register)<first_mm_imreg then
|
||||
begin
|
||||
getcpuregister(list,paraloc.register);
|
||||
ungetcpuregister(list,paraloc.register);
|
||||
end;
|
||||
a_loadmm_reg_ref(list,paraloc.size,paraloc.size,paraloc.register,ref,shuffle);
|
||||
end;
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER:
|
||||
begin
|
||||
if getsupreg(paraloc.register)<first_fpu_imreg then
|
||||
begin
|
||||
getcpuregister(list,paraloc.register);
|
||||
ungetcpuregister(list,paraloc.register);
|
||||
end;
|
||||
a_loadfpu_reg_ref(list,paraloc.size,paraloc.register,ref);
|
||||
end;
|
||||
LOC_REFERENCE:
|
||||
begin
|
||||
reference_reset_base(href,paraloc.reference.index,paraloc.reference.offset);
|
||||
{ use concatcopy, because it can also be a float which fails when
|
||||
load_ref_ref is used }
|
||||
g_concatcopy(list,href,ref,tcgsize2size[paraloc.size],false);
|
||||
end;
|
||||
else
|
||||
internalerror(2002081302);
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
href:=ref;
|
||||
gen_load(paraloc.location^,href);
|
||||
if assigned(paraloc.location^.next) then
|
||||
begin
|
||||
inc(href.offset,TCGSize2Size[paraloc.location^.size]);
|
||||
gen_load(paraloc.location^.next^,href);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg.a_loadany_param_reg(list : taasmoutput;const paraloc : TCGPara;const reg:tregister;shuffle : pmmshuffle);
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
paraloc.check_simple_location;
|
||||
case paraloc.location^.loc of
|
||||
LOC_CREGISTER,
|
||||
LOC_REGISTER:
|
||||
begin
|
||||
if getsupreg(paraloc.location^.register)<first_int_imreg then
|
||||
begin
|
||||
getcpuregister(list,paraloc.location^.register);
|
||||
ungetcpuregister(list,paraloc.location^.register);
|
||||
end;
|
||||
a_load_reg_reg(list,paraloc.location^.size,paraloc.location^.size,paraloc.location^.register,reg)
|
||||
end;
|
||||
LOC_CFPUREGISTER,
|
||||
LOC_FPUREGISTER:
|
||||
begin
|
||||
if getsupreg(paraloc.location^.register)<first_fpu_imreg then
|
||||
begin
|
||||
getcpuregister(list,paraloc.location^.register);
|
||||
ungetcpuregister(list,paraloc.location^.register);
|
||||
end;
|
||||
a_loadfpu_reg_reg(list,paraloc.location^.size,paraloc.location^.register,reg);
|
||||
end;
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER:
|
||||
begin
|
||||
if getsupreg(paraloc.location^.register)<first_mm_imreg then
|
||||
begin
|
||||
getcpuregister(list,paraloc.location^.register);
|
||||
ungetcpuregister(list,paraloc.location^.register);
|
||||
end;
|
||||
a_loadmm_reg_reg(list,paraloc.location^.size,paraloc.location^.size,paraloc.location^.register,reg,shuffle);
|
||||
end;
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE:
|
||||
begin
|
||||
reference_reset_base(href,paraloc.location^.reference.index,paraloc.location^.reference.offset);
|
||||
a_load_ref_reg(list,paraloc.location^.size,paraloc.location^.size,href,reg);
|
||||
end;
|
||||
else
|
||||
internalerror(2003053010);
|
||||
end
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
some generic implementations
|
||||
****************************************************************************}
|
||||
@ -2226,7 +2111,13 @@ finalization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.174 2004-10-05 20:41:01 peter
|
||||
Revision 1.175 2004-10-10 20:22:53 peter
|
||||
* symtable allocation rewritten
|
||||
* loading of parameters to local temps/regs cleanup
|
||||
* regvar support for parameters
|
||||
* regvar support for staticsymtable (main body)
|
||||
|
||||
Revision 1.174 2004/10/05 20:41:01 peter
|
||||
* more spilling rewrites
|
||||
|
||||
Revision 1.173 2004/09/29 18:55:40 florian
|
||||
|
@ -549,18 +549,24 @@ type
|
||||
valid_for_var(left);
|
||||
end;
|
||||
|
||||
if paraitem.paratyp in [vs_var,vs_const] then
|
||||
begin
|
||||
{ Causes problems with const ansistrings if also }
|
||||
{ done for vs_const (JM) }
|
||||
if paraitem.paratyp = vs_var then
|
||||
set_unique(left);
|
||||
make_not_regable(left);
|
||||
end;
|
||||
if paraitem.paratyp = vs_var then
|
||||
set_unique(left);
|
||||
|
||||
{ ansistrings out paramaters doesn't need to be }
|
||||
{ unique, they are finalized }
|
||||
if paraitem.paratyp=vs_out then
|
||||
{ When the address needs to be pushed then the register is
|
||||
not regable. Exception is when the location is also a var
|
||||
parameter and we can pass the address transparently }
|
||||
if (
|
||||
not(
|
||||
paraitem.is_hidden and
|
||||
(left.resulttype.def.deftype in [pointerdef,classrefdef])
|
||||
) and
|
||||
paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,
|
||||
aktcallnode.procdefinition.proccalloption) and
|
||||
not(
|
||||
(left.nodetype=loadn) and
|
||||
(tloadnode(left).is_addr_param_load)
|
||||
)
|
||||
) then
|
||||
make_not_regable(left);
|
||||
|
||||
if do_count then
|
||||
@ -2386,7 +2392,13 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.249 2004-10-08 17:09:43 peter
|
||||
Revision 1.250 2004-10-10 20:22:53 peter
|
||||
* symtable allocation rewritten
|
||||
* loading of parameters to local temps/regs cleanup
|
||||
* regvar support for parameters
|
||||
* regvar support for staticsymtable (main body)
|
||||
|
||||
Revision 1.249 2004/10/08 17:09:43 peter
|
||||
* tvarsym.varregable added, split vo_regable from varoptions
|
||||
|
||||
Revision 1.248 2004/09/21 17:25:12 peter
|
||||
|
@ -98,12 +98,10 @@ interface
|
||||
procedure insertconstdata(sym : ttypedconstsym);
|
||||
procedure insertbssdata(sym : tvarsym);
|
||||
|
||||
procedure gen_alloc_localst(list:TAAsmoutput;st:tlocalsymtable);
|
||||
procedure gen_free_localst(list:TAAsmoutput;st:tlocalsymtable);
|
||||
procedure gen_alloc_parast(list:TAAsmoutput;st:tparasymtable);
|
||||
procedure gen_alloc_symtable(list:TAAsmoutput;st:tsymtable);
|
||||
procedure gen_free_symtable(list:TAAsmoutput;st:tsymtable);
|
||||
procedure gen_alloc_inline_parast(list:TAAsmoutput;pd:tprocdef);
|
||||
procedure gen_alloc_inline_funcret(list:TAAsmoutput;pd:tprocdef);
|
||||
procedure gen_free_parast(list:TAAsmoutput;st:tparasymtable);
|
||||
|
||||
{ rtti and init/final }
|
||||
procedure generate_rtti(p:Ttypesym);
|
||||
@ -1079,7 +1077,7 @@ implementation
|
||||
begin
|
||||
cg.getcpuregister(list,resloc.registerlow);
|
||||
cg.ungetcpuregister(list,resloc.registerlow);
|
||||
// for the optimizer
|
||||
{ for the optimizer }
|
||||
cg.a_reg_alloc(list,resloc.registerlow);
|
||||
end;
|
||||
case restmploc.loc of
|
||||
@ -1099,7 +1097,7 @@ implementation
|
||||
begin
|
||||
cg.getcpuregister(list,resloc.registerhigh);
|
||||
cg.ungetcpuregister(list,resloc.registerhigh);
|
||||
// for the optimizer
|
||||
{ for the optimizer }
|
||||
cg.a_reg_alloc(list,resloc.registerhigh);
|
||||
end;
|
||||
case restmploc.loc of
|
||||
@ -1124,7 +1122,7 @@ implementation
|
||||
begin
|
||||
cg.getcpuregister(list,funcretloc^.register);
|
||||
cg.ungetcpuregister(list,hreg);
|
||||
// for the optimizer
|
||||
{ for the optimizer }
|
||||
cg.a_reg_alloc(list,funcretloc^.register);
|
||||
end;
|
||||
cg.a_load_loc_reg(list,restmploc.size,restmploc,hreg);
|
||||
@ -1159,70 +1157,176 @@ implementation
|
||||
|
||||
|
||||
procedure gen_load_para_value(list:TAAsmoutput);
|
||||
var
|
||||
hp : tparaitem;
|
||||
hiparaloc,
|
||||
paraloc : pcgparalocation;
|
||||
begin
|
||||
{ Store register parameters in reference or in register variable }
|
||||
if assigned(current_procinfo.procdef.parast) and
|
||||
not (po_assembler in current_procinfo.procdef.procoptions) then
|
||||
begin
|
||||
{ move register parameters which aren't regable into memory }
|
||||
{ we do this before init_paras because that one calls routines which may overwrite these }
|
||||
{ registers and it also expects the values to be in memory }
|
||||
hp:=tparaitem(current_procinfo.procdef.para.first);
|
||||
while assigned(hp) do
|
||||
begin
|
||||
paraloc:=hp.paraloc[calleeside].location;
|
||||
if not assigned(paraloc) then
|
||||
internalerror(200408203);
|
||||
hiparaloc:=paraloc^.next;
|
||||
case tvarsym(hp.parasym).localloc.loc of
|
||||
LOC_REGISTER,
|
||||
LOC_MMREGISTER,
|
||||
LOC_FPUREGISTER:
|
||||
begin
|
||||
{ cg.a_load_param_reg will first allocate and then deallocate paraloc }
|
||||
{ register (if the parameter resides in a register) and then allocate }
|
||||
{ the regvar (which is currently not allocated) }
|
||||
cg.a_loadany_param_reg(list,hp.paraloc[calleeside],tvarsym(hp.parasym).localloc.register,mms_movescalar);
|
||||
end;
|
||||
LOC_REFERENCE :
|
||||
begin
|
||||
if paraloc^.loc<>LOC_REFERENCE then
|
||||
begin
|
||||
if getregtype(paraloc^.register)=R_INTREGISTER then
|
||||
begin
|
||||
{ Release parameter register }
|
||||
if getsupreg(paraloc^.register)<first_int_imreg then
|
||||
begin
|
||||
{$ifndef cpu64bit}
|
||||
if assigned(hiparaloc) then
|
||||
begin
|
||||
cg.getcpuregister(list,hiparaloc^.register);
|
||||
cg.ungetcpuregister(list,hiparaloc^.register);
|
||||
end;
|
||||
{$endif cpu64bit}
|
||||
cg.getcpuregister(list,paraloc^.register);
|
||||
cg.ungetcpuregister(list,paraloc^.register);
|
||||
end;
|
||||
end;
|
||||
cg.a_loadany_param_ref(list,hp.paraloc[calleeside],tvarsym(hp.parasym).localloc.reference,mms_movescalar);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
internalerror(200309185);
|
||||
|
||||
|
||||
procedure get_para(const paraloc:TCGParaLocation);
|
||||
begin
|
||||
case paraloc.loc of
|
||||
LOC_REGISTER :
|
||||
begin
|
||||
if getsupreg(paraloc.register)<first_int_imreg then
|
||||
cg.getcpuregister(list,paraloc.register);
|
||||
end;
|
||||
hp:=tparaitem(hp.next);
|
||||
LOC_MMREGISTER :
|
||||
begin
|
||||
if getsupreg(paraloc.register)<first_mm_imreg then
|
||||
cg.getcpuregister(list,paraloc.register);
|
||||
end;
|
||||
LOC_FPUREGISTER :
|
||||
begin
|
||||
if getsupreg(paraloc.register)<first_fpu_imreg then
|
||||
cg.getcpuregister(list,paraloc.register);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure unget_para(const paraloc:TCGParaLocation);
|
||||
begin
|
||||
case paraloc.loc of
|
||||
LOC_REGISTER :
|
||||
begin
|
||||
if getsupreg(paraloc.register)<first_int_imreg then
|
||||
cg.ungetcpuregister(list,paraloc.register);
|
||||
end;
|
||||
LOC_MMREGISTER :
|
||||
begin
|
||||
if getsupreg(paraloc.register)<first_mm_imreg then
|
||||
cg.ungetcpuregister(list,paraloc.register);
|
||||
end;
|
||||
LOC_FPUREGISTER :
|
||||
begin
|
||||
if getsupreg(paraloc.register)<first_fpu_imreg then
|
||||
cg.ungetcpuregister(list,paraloc.register);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure gen_load_ref(const paraloc:TCGParaLocation;const ref:treference);
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
case paraloc.loc of
|
||||
LOC_REGISTER :
|
||||
cg.a_load_reg_ref(list,paraloc.size,paraloc.size,paraloc.register,ref);
|
||||
LOC_MMREGISTER :
|
||||
cg.a_loadmm_reg_ref(list,paraloc.size,paraloc.size,paraloc.register,ref,mms_movescalar);
|
||||
LOC_FPUREGISTER :
|
||||
cg.a_loadfpu_reg_ref(list,paraloc.size,paraloc.register,ref);
|
||||
LOC_REFERENCE :
|
||||
begin
|
||||
reference_reset_base(href,paraloc.reference.index,paraloc.reference.offset);
|
||||
{ use concatcopy, because it can also be a float which fails when
|
||||
load_ref_ref is used. Don't copy data when the references are equal }
|
||||
if not((href.base=ref.base) and (href.offset=ref.offset)) then
|
||||
cg.g_concatcopy(list,href,ref,tcgsize2size[paraloc.size],false);
|
||||
end;
|
||||
else
|
||||
internalerror(2002081302);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure gen_load_reg(const paraloc:TCGParaLocation;reg:tregister);
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
case paraloc.loc of
|
||||
LOC_REGISTER :
|
||||
cg.a_load_reg_reg(list,paraloc.size,paraloc.size,paraloc.register,reg);
|
||||
LOC_MMREGISTER :
|
||||
cg.a_loadmm_reg_reg(list,paraloc.size,paraloc.size,paraloc.register,reg,mms_movescalar);
|
||||
LOC_FPUREGISTER :
|
||||
cg.a_loadfpu_reg_reg(list,paraloc.size,paraloc.register,reg);
|
||||
LOC_REFERENCE :
|
||||
begin
|
||||
reference_reset_base(href,paraloc.reference.index,paraloc.reference.offset);
|
||||
cg.a_load_ref_reg(list,paraloc.size,paraloc.size,href,reg);
|
||||
end;
|
||||
else
|
||||
internalerror(2002081302);
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
hp : tparaitem;
|
||||
paraloc : pcgparalocation;
|
||||
href : treference;
|
||||
begin
|
||||
if (po_assembler in current_procinfo.procdef.procoptions) then
|
||||
exit;
|
||||
|
||||
{ Allocate registers used by parameters }
|
||||
hp:=tparaitem(current_procinfo.procdef.para.first);
|
||||
while assigned(hp) do
|
||||
begin
|
||||
paraloc:=hp.paraloc[calleeside].location;
|
||||
while assigned(paraloc) do
|
||||
begin
|
||||
if paraloc^.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER] then
|
||||
get_para(paraloc^);
|
||||
paraloc:=paraloc^.next;
|
||||
end;
|
||||
hp:=tparaitem(hp.next);
|
||||
end;
|
||||
|
||||
{ Copy parameters to local references/registers }
|
||||
hp:=tparaitem(current_procinfo.procdef.para.first);
|
||||
while assigned(hp) do
|
||||
begin
|
||||
paraloc:=hp.paraloc[calleeside].location;
|
||||
if not assigned(paraloc) then
|
||||
internalerror(200408203);
|
||||
case tvarsym(hp.parasym).localloc.loc of
|
||||
LOC_REFERENCE :
|
||||
begin
|
||||
href:=tvarsym(hp.parasym).localloc.reference;
|
||||
while assigned(paraloc) do
|
||||
begin
|
||||
unget_para(paraloc^);
|
||||
gen_load_ref(paraloc^,href);
|
||||
inc(href.offset,TCGSize2Size[paraloc^.size]);
|
||||
paraloc:=paraloc^.next;
|
||||
end;
|
||||
end;
|
||||
LOC_CREGISTER,
|
||||
LOC_CMMREGISTER,
|
||||
LOC_CFPUREGISTER :
|
||||
begin
|
||||
href:=tvarsym(hp.parasym).localloc.reference;
|
||||
{$ifndef cpu64bit}
|
||||
if tvarsym(hp.parasym).localloc.size in [OS_64,OS_S64] then
|
||||
begin
|
||||
{ First 32bits }
|
||||
unget_para(paraloc^);
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
gen_load_reg(paraloc^,tvarsym(hp.parasym).localloc.registerhigh)
|
||||
else
|
||||
gen_load_reg(paraloc^,tvarsym(hp.parasym).localloc.registerlow);
|
||||
{ Second 32bits }
|
||||
if not assigned(paraloc^.next) then
|
||||
internalerror(200410104);
|
||||
unget_para(paraloc^);
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
gen_load_reg(paraloc^,tvarsym(hp.parasym).localloc.registerlow)
|
||||
else
|
||||
gen_load_reg(paraloc^,tvarsym(hp.parasym).localloc.registerhigh);
|
||||
end
|
||||
else
|
||||
{$endif cpu64bit}
|
||||
begin
|
||||
unget_para(paraloc^);
|
||||
gen_load_reg(paraloc^,tvarsym(hp.parasym).localloc.register);
|
||||
if assigned(paraloc^.next) then
|
||||
internalerror(200410105);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
hp:=tparaitem(hp.next);
|
||||
end;
|
||||
|
||||
{ generate copies of call by value parameters, must be done before
|
||||
the initialization and body is parsed because the refcounts are
|
||||
incremented using the local copies }
|
||||
if not(po_assembler in current_procinfo.procdef.procoptions) then
|
||||
current_procinfo.procdef.parast.foreach_static({$ifndef TP}@{$endif}copyvalueparas,list);
|
||||
current_procinfo.procdef.parast.foreach_static({$ifndef TP}@{$endif}copyvalueparas,list);
|
||||
end;
|
||||
|
||||
|
||||
@ -1706,47 +1810,125 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure gen_alloc_localst(list:TAAsmoutput;st:tlocalsymtable);
|
||||
procedure gen_alloc_symtable(list:TAAsmoutput;st:tsymtable);
|
||||
|
||||
function getregvar(v:tvarregable;size:tcgsize):tregister;
|
||||
begin
|
||||
case v of
|
||||
vr_intreg :
|
||||
result:=cg.getintregister(list,size);
|
||||
vr_fpureg :
|
||||
result:=cg.getfpuregister(list,size);
|
||||
vr_mmreg :
|
||||
result:=cg.getmmregister(list,size);
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
sym : tsym;
|
||||
sym : tsym;
|
||||
isaddr : boolean;
|
||||
cgsize : tcgsize;
|
||||
begin
|
||||
sym:=tsym(st.symindex.first);
|
||||
while assigned(sym) do
|
||||
begin
|
||||
{ Only allocate space for referenced locals }
|
||||
if (sym.typ=varsym) and
|
||||
(tvarsym(sym).refs>0) then
|
||||
if (sym.typ=varsym) then
|
||||
begin
|
||||
with tvarsym(sym) do
|
||||
begin
|
||||
{$ifndef OLDREGVARS}
|
||||
{ When there is assembler code we can't use regvars }
|
||||
if (cs_regvars in aktglobalswitches) and
|
||||
not(pi_has_assembler_block in current_procinfo.flags) and
|
||||
not(pi_uses_exceptions in current_procinfo.flags) and
|
||||
(varregable<>vr_none) then
|
||||
{ Parameters passed to assembler procedures need to be kept
|
||||
in the original location }
|
||||
if (st.symtabletype=parasymtable) and
|
||||
(po_assembler in current_procinfo.procdef.procoptions) then
|
||||
begin
|
||||
localloc.loc:=LOC_CREGISTER;
|
||||
localloc.size:=def_cgsize(vartype.def);
|
||||
localloc.register:=cg.getintregister(list,localloc.size);
|
||||
if cs_asm_source in aktglobalswitches then
|
||||
begin
|
||||
if (cs_no_regalloc in aktglobalswitches) then
|
||||
list.concat(Tai_comment.Create(strpnew('Local '+realname+' located in register '+
|
||||
std_regname(localloc.register))))
|
||||
else
|
||||
list.concat(Tai_comment.Create(strpnew('Local '+realname+' located in register')));
|
||||
end;
|
||||
paraitem.paraloc[calleeside].get_location(localloc);
|
||||
end
|
||||
else
|
||||
{$endif NOT OLDREGVARS}
|
||||
begin
|
||||
localloc.loc:=LOC_REFERENCE;
|
||||
localloc.size:=def_cgsize(vartype.def);
|
||||
tg.GetLocal(list,getvaluesize,vartype.def,localloc.reference);
|
||||
if cs_asm_source in aktglobalswitches then
|
||||
list.concat(Tai_comment.Create(strpnew('Local '+realname+' located at '+
|
||||
std_regname(localloc.reference.base)+tostr_with_plus(localloc.reference.offset))));
|
||||
isaddr:=(st.symtabletype=parasymtable) and
|
||||
paramanager.push_addr_param(varspez,vartype.def,current_procinfo.procdef.proccalloption);
|
||||
if isaddr then
|
||||
cgsize:=OS_ADDR
|
||||
else
|
||||
cgsize:=def_cgsize(vartype.def);
|
||||
{$ifndef OLDREGVARS}
|
||||
{ When there is assembler code we can't use regvars }
|
||||
if (cs_regvars in aktglobalswitches) and
|
||||
not(pi_has_assembler_block in current_procinfo.flags) and
|
||||
not(pi_uses_exceptions in current_procinfo.flags) and
|
||||
(varregable<>vr_none) then
|
||||
begin
|
||||
localloc.loc:=LOC_CREGISTER;
|
||||
localloc.size:=cgsize;
|
||||
{$ifndef cpu64bit}
|
||||
if cgsize in [OS_64,OS_S64] then
|
||||
begin
|
||||
localloc.registerlow:=getregvar(varregable,OS_32);
|
||||
localloc.registerhigh:=getregvar(varregable,OS_32);
|
||||
end
|
||||
else
|
||||
{$endif cpu64bit}
|
||||
localloc.register:=getregvar(varregable,cgsize);
|
||||
end
|
||||
else
|
||||
{$endif NOT OLDREGVARS}
|
||||
begin
|
||||
localloc.loc:=LOC_REFERENCE;
|
||||
localloc.size:=cgsize;
|
||||
case st.symtabletype of
|
||||
parasymtable :
|
||||
begin
|
||||
{ Reuse the parameter location for values to are at a single location on the stack }
|
||||
if (paraitem.paraloc[calleeside].is_simple_reference) then
|
||||
begin
|
||||
reference_reset_base(localloc.reference,paraitem.paraloc[calleeside].location^.reference.index,
|
||||
paraitem.paraloc[calleeside].location^.reference.offset);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if isaddr then
|
||||
tg.GetLocal(list,sizeof(aint),voidpointertype.def,localloc.reference)
|
||||
else
|
||||
tg.GetLocal(list,getvaluesize,vartype.def,localloc.reference);
|
||||
end;
|
||||
end;
|
||||
localsymtable,
|
||||
stt_exceptsymtable :
|
||||
begin
|
||||
tg.GetLocal(list,getvaluesize,vartype.def,localloc.reference);
|
||||
end;
|
||||
staticsymtable :
|
||||
begin
|
||||
{ PIC, DLL and Threadvar need extra code and are handled in ncgld }
|
||||
if not(cs_create_pic in aktmoduleswitches) and
|
||||
not(vo_is_dll_var in varoptions) and
|
||||
not(vo_is_thread_var in varoptions) then
|
||||
reference_reset_symbol(localloc.reference,objectlibrary.newasmsymbol(mangledname,AB_EXTERNAL,AT_DATA),0);
|
||||
end;
|
||||
else
|
||||
internalerror(200410103);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if cs_asm_source in aktglobalswitches then
|
||||
begin
|
||||
case localloc.loc of
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER :
|
||||
begin
|
||||
if (cs_no_regalloc in aktglobalswitches) then
|
||||
list.concat(Tai_comment.Create(strpnew('Var '+realname+' located in register '+
|
||||
std_regname(localloc.register))))
|
||||
else
|
||||
list.concat(Tai_comment.Create(strpnew('Var '+realname+' located in register')));
|
||||
end;
|
||||
LOC_REFERENCE :
|
||||
begin
|
||||
if not assigned(localloc.reference.symbol) then
|
||||
list.concat(Tai_comment.Create(strpnew('Var '+realname+' located at '+
|
||||
std_regname(localloc.reference.base)+tostr_with_plus(localloc.reference.offset))));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -1755,15 +1937,14 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure gen_free_localst(list:TAAsmoutput;st:tlocalsymtable);
|
||||
procedure gen_free_symtable(list:TAAsmoutput;st:tsymtable);
|
||||
var
|
||||
sym : tsym;
|
||||
begin
|
||||
sym:=tsym(st.symindex.first);
|
||||
while assigned(sym) do
|
||||
begin
|
||||
if (sym.typ=varsym) and
|
||||
(tvarsym(sym).refs>0) then
|
||||
if (sym.typ=varsym) then
|
||||
begin
|
||||
with tvarsym(sym) do
|
||||
begin
|
||||
@ -1774,92 +1955,15 @@ implementation
|
||||
LOC_CREGISTER :
|
||||
cg.a_reg_sync(list,localloc.register);
|
||||
LOC_REFERENCE :
|
||||
tg.Ungetlocal(list,localloc.reference);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
sym:=tsym(sym.indexnext);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure gen_alloc_parast(list:TAAsmoutput;st:tparasymtable);
|
||||
var
|
||||
sym : tsym;
|
||||
begin
|
||||
sym:=tsym(st.symindex.first);
|
||||
while assigned(sym) do
|
||||
begin
|
||||
if sym.typ=varsym then
|
||||
begin
|
||||
with tvarsym(sym) do
|
||||
begin
|
||||
if not(po_assembler in current_procinfo.procdef.procoptions) then
|
||||
begin
|
||||
case paraitem.paraloc[calleeside].location^.loc of
|
||||
{$ifdef powerpc}
|
||||
LOC_REFERENCE,
|
||||
{$endif powerpc}
|
||||
LOC_MMREGISTER,
|
||||
LOC_FPUREGISTER,
|
||||
LOC_REGISTER:
|
||||
begin
|
||||
(*
|
||||
if paraitem.paraloc[calleeside].register=NR_NO then
|
||||
begin
|
||||
paraitem.paraloc[calleeside].loc:=LOC_REGISTER;
|
||||
paraitem.paraloc[calleeside].size:=paraitem.paraloc[calleeside].size;
|
||||
{$ifndef cpu64bit}
|
||||
if paraitem.paraloc[calleeside].size in [OS_64,OS_S64] then
|
||||
begin
|
||||
paraitem.paraloc[calleeside].registerlow:=cg.getregisterint(list,OS_32);
|
||||
paraitem.paraloc[calleeside].registerhigh:=cg.getregisterint(list,OS_32);
|
||||
end
|
||||
else
|
||||
{$endif cpu64bit}
|
||||
paraitem.paraloc[calleeside].register:=cg.getregisterint(list,localloc.size);
|
||||
end;
|
||||
*)
|
||||
(*
|
||||
{$warning TODO Allocate register paras}
|
||||
localloc.loc:=LOC_REGISTER;
|
||||
localloc.size:=paraitem.paraloc[calleeside].size;
|
||||
{$ifndef cpu64bit}
|
||||
if localloc.size in [OS_64,OS_S64] then
|
||||
begin
|
||||
localloc.registerlow:=cg.getregisterint(list,OS_32);
|
||||
localloc.registerhigh:=cg.getregisterint(list,OS_32);
|
||||
end
|
||||
else
|
||||
{$endif cpu64bit}
|
||||
localloc.register:=cg.getregisterint(list,localloc.size);
|
||||
*)
|
||||
localloc.loc:=LOC_REFERENCE;
|
||||
if paramanager.push_addr_param(paraitem.paratyp,vartype.def,current_procinfo.procdef.proccalloption) then
|
||||
begin
|
||||
localloc.size:=OS_ADDR;
|
||||
tg.GetLocal(list,tcgsize2size[localloc.size],voidpointertype.def,localloc.reference);
|
||||
end
|
||||
else
|
||||
begin
|
||||
localloc.size:=paraitem.paraloc[calleeside].size;
|
||||
tg.GetLocal(list,tcgsize2size[localloc.size],vartype.def,localloc.reference);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
paraitem.paraloc[calleeside].get_location(localloc);
|
||||
end;
|
||||
end
|
||||
else
|
||||
paraitem.paraloc[calleeside].get_location(localloc);
|
||||
if cs_asm_source in aktglobalswitches then
|
||||
case localloc.loc of
|
||||
LOC_REFERENCE :
|
||||
begin
|
||||
list.concat(Tai_comment.Create(strpnew('Para '+realname+' located at '+
|
||||
std_regname(localloc.reference.base)+tostr_with_plus(localloc.reference.offset))));
|
||||
begin
|
||||
case st.symtabletype of
|
||||
localsymtable,
|
||||
parasymtable,
|
||||
stt_exceptsymtable :
|
||||
tg.Ungetlocal(list,localloc.reference);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
sym:=tsym(sym.indexnext);
|
||||
@ -1997,33 +2101,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure gen_free_parast(list:TAAsmoutput;st:tparasymtable);
|
||||
var
|
||||
sym : tsym;
|
||||
begin
|
||||
sym:=tsym(st.symindex.first);
|
||||
while assigned(sym) do
|
||||
begin
|
||||
if sym.typ=varsym then
|
||||
begin
|
||||
with tvarsym(sym) do
|
||||
begin
|
||||
{ Note: We need to keep the data available in memory
|
||||
for the sub procedures that can access local data
|
||||
in the parent procedures }
|
||||
case localloc.loc of
|
||||
LOC_REGISTER :
|
||||
cg.a_reg_sync(list,localloc.register);
|
||||
LOC_REFERENCE :
|
||||
tg.UngetLocal(list,localloc.reference);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
sym:=tsym(sym.indexnext);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ persistent rtti generation }
|
||||
procedure generate_rtti(p:Ttypesym);
|
||||
var
|
||||
@ -2098,7 +2175,13 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.222 2004-10-09 10:51:13 olle
|
||||
Revision 1.223 2004-10-10 20:22:53 peter
|
||||
* symtable allocation rewritten
|
||||
* loading of parameters to local temps/regs cleanup
|
||||
* regvar support for parameters
|
||||
* regvar support for staticsymtable (main body)
|
||||
|
||||
Revision 1.222 2004/10/09 10:51:13 olle
|
||||
* Refs to DEBUGINFO_<x> is now not inserted for target MacOS
|
||||
|
||||
Revision 1.221 2004/10/08 20:52:07 florian
|
||||
|
@ -47,6 +47,7 @@ interface
|
||||
procedure buildderefimpl;override;
|
||||
procedure derefimpl;override;
|
||||
procedure set_mp(p:tnode);
|
||||
function is_addr_param_load:boolean;
|
||||
function getcopy : tnode;override;
|
||||
function pass_1 : tnode;override;
|
||||
function det_resulttype:tnode;override;
|
||||
@ -227,6 +228,16 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tloadnode.is_addr_param_load:boolean;
|
||||
begin
|
||||
result:=(symtable.symtabletype=parasymtable) and
|
||||
(symtableentry.typ=varsym) and
|
||||
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);
|
||||
end;
|
||||
|
||||
|
||||
function tloadnode.det_resulttype:tnode;
|
||||
begin
|
||||
result:=nil;
|
||||
@ -1145,7 +1156,13 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.131 2004-10-08 17:09:43 peter
|
||||
Revision 1.132 2004-10-10 20:22:53 peter
|
||||
* symtable allocation rewritten
|
||||
* loading of parameters to local temps/regs cleanup
|
||||
* regvar support for parameters
|
||||
* regvar support for staticsymtable (main body)
|
||||
|
||||
Revision 1.131 2004/10/08 17:09:43 peter
|
||||
* tvarsym.varregable added, split vo_regable from varoptions
|
||||
|
||||
Revision 1.130 2004/10/06 19:26:50 jonas
|
||||
|
@ -57,6 +57,7 @@ unit parabase;
|
||||
destructor done;
|
||||
procedure reset;
|
||||
procedure check_simple_location;
|
||||
function is_simple_reference:boolean;
|
||||
function add_location:pcgparalocation;
|
||||
procedure get_location(var newloc:tlocation);
|
||||
end;
|
||||
@ -145,6 +146,20 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tcgpara.is_simple_reference:boolean;
|
||||
begin
|
||||
if not assigned(location) then
|
||||
internalerror(200410102);
|
||||
{$ifdef powerpc}
|
||||
{ Powerpc always needs a copy in a local temp }
|
||||
result:=false;
|
||||
{$else}
|
||||
result:=not assigned(location^.next) and
|
||||
(location^.loc=LOC_REFERENCE);
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgpara.get_location(var newloc:tlocation);
|
||||
begin
|
||||
if not assigned(location) then
|
||||
@ -192,7 +207,13 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.2 2004-09-21 17:25:12 peter
|
||||
Revision 1.3 2004-10-10 20:22:53 peter
|
||||
* symtable allocation rewritten
|
||||
* loading of parameters to local temps/regs cleanup
|
||||
* regvar support for parameters
|
||||
* regvar support for staticsymtable (main body)
|
||||
|
||||
Revision 1.2 2004/09/21 17:25:12 peter
|
||||
* paraloc branch merged
|
||||
|
||||
Revision 1.1.2.2 2004/09/14 19:09:37 jonas
|
||||
|
@ -678,9 +678,8 @@ implementation
|
||||
|
||||
{ Allocate space in temp/registers for parast and localst }
|
||||
aktfilepos:=entrypos;
|
||||
gen_alloc_parast(aktproccode,tparasymtable(procdef.parast));
|
||||
if procdef.localst.symtabletype=localsymtable then
|
||||
gen_alloc_localst(aktproccode,tlocalsymtable(procdef.localst));
|
||||
gen_alloc_symtable(aktproccode,tparasymtable(procdef.parast));
|
||||
gen_alloc_symtable(aktproccode,tlocalsymtable(procdef.localst));
|
||||
|
||||
{ Store temp offset for information about 'real' temps }
|
||||
tempstart:=tg.lasttemp;
|
||||
@ -774,9 +773,8 @@ implementation
|
||||
{ Free space in temp/registers for parast and localst, must be
|
||||
done after gen_entry_code }
|
||||
aktfilepos:=exitpos;
|
||||
if procdef.localst.symtabletype=localsymtable then
|
||||
gen_free_localst(aktproccode,tlocalsymtable(procdef.localst));
|
||||
gen_free_parast(aktproccode,tparasymtable(procdef.parast));
|
||||
gen_free_symtable(aktproccode,tlocalsymtable(procdef.localst));
|
||||
gen_free_symtable(aktproccode,tparasymtable(procdef.parast));
|
||||
|
||||
{ The procedure body is finished, we can now
|
||||
allocate the registers }
|
||||
@ -1393,7 +1391,13 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.207 2004-09-26 17:45:30 peter
|
||||
Revision 1.208 2004-10-10 20:22:53 peter
|
||||
* symtable allocation rewritten
|
||||
* loading of parameters to local temps/regs cleanup
|
||||
* regvar support for parameters
|
||||
* regvar support for staticsymtable (main body)
|
||||
|
||||
Revision 1.207 2004/09/26 17:45:30 peter
|
||||
* simple regvar support, not yet finished
|
||||
|
||||
Revision 1.206 2004/09/21 17:25:12 peter
|
||||
|
@ -1627,7 +1627,11 @@ implementation
|
||||
_vartype := newtype;
|
||||
{ can we load the value into a register ? }
|
||||
if not assigned(owner) or
|
||||
(owner.symtabletype in [localsymtable,parasymtable]) then
|
||||
(owner.symtabletype in [localsymtable,parasymtable]) or
|
||||
(
|
||||
(owner.symtabletype=staticsymtable) and
|
||||
not(cs_create_pic in aktmoduleswitches)
|
||||
) then
|
||||
begin
|
||||
if tstoreddef(vartype.def).is_intregable then
|
||||
varregable:=vr_intreg
|
||||
@ -2218,7 +2222,13 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.181 2004-10-10 09:31:28 peter
|
||||
Revision 1.182 2004-10-10 20:22:53 peter
|
||||
* symtable allocation rewritten
|
||||
* loading of parameters to local temps/regs cleanup
|
||||
* regvar support for parameters
|
||||
* regvar support for staticsymtable (main body)
|
||||
|
||||
Revision 1.181 2004/10/10 09:31:28 peter
|
||||
regvar ppu writing doesn't affect any crc
|
||||
|
||||
Revision 1.180 2004/10/08 17:09:43 peter
|
||||
|
Loading…
Reference in New Issue
Block a user