* support register parameters for inlined procedures + some inline

cleanups
This commit is contained in:
Jonas Maebe 2004-07-09 23:41:04 +00:00
parent 1dd5fc2b47
commit f1bda1700a
4 changed files with 222 additions and 165 deletions

View File

@ -839,32 +839,44 @@ implementation
{$ifndef cpu64bit}
if (locpara.size in [OS_S64,OS_64]) then
begin
getexplicitregister(list,locpara.registerlow);
getexplicitregister(list,locpara.registerhigh);
ungetregister(list,locpara.registerlow);
ungetregister(list,locpara.registerhigh);
if getsupreg(locpara.registerlow)<first_int_imreg then
begin
getexplicitregister(list,locpara.registerlow);
getexplicitregister(list,locpara.registerhigh);
ungetregister(list,locpara.registerlow);
ungetregister(list,locpara.registerhigh);
end;
cg64.a_load64_reg_ref(list,locpara.register64,ref)
end
else
{$endif cpu64bit}
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
if getsupreg(locpara.register)<first_int_imreg then
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
end;
a_load_reg_ref(list,locpara.size,locpara.size,locpara.register,ref);
end;
end;
LOC_MMREGISTER,
LOC_CMMREGISTER:
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
if getsupreg(locpara.register)<first_mm_imreg then
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
end;
a_loadmm_reg_ref(list,locpara.size,locpara.size,locpara.register,ref,shuffle);
end;
LOC_FPUREGISTER,
LOC_CFPUREGISTER:
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
if getsupreg(locpara.register)<first_fpu_imreg then
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
end;
a_loadfpu_reg_ref(list,locpara.size,locpara.register,ref);
end;
else
@ -883,8 +895,11 @@ implementation
begin
if not(locpara.size in [OS_S64,OS_64]) then
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
if getsupreg(locpara.register)<first_int_imreg then
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
end;
{
This is now a normal imaginary register, allocated the usual way (JM)
getexplicitregister(list,reg);
@ -898,8 +913,11 @@ implementation
LOC_FPUREGISTER:
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
if getsupreg(locpara.register)<first_fpu_imreg then
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
end;
{
This is now a normal imaginary register, allocated the usual way (JM)
getexplicitregister(list,reg);
@ -909,8 +927,11 @@ implementation
LOC_MMREGISTER,
LOC_CMMREGISTER:
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
if getsupreg(locpara.register)<first_mm_imreg then
begin
getexplicitregister(list,locpara.register);
ungetregister(list,locpara.register);
end;
{
This is now a normal imaginary register, allocated the usual way (JM)
getexplicitregister(list,reg);
@ -2174,7 +2195,11 @@ finalization
end.
{
$Log$
Revision 1.167 2004-07-03 11:47:04 peter
Revision 1.168 2004-07-09 23:41:04 jonas
* support register parameters for inlined procedures + some inline
cleanups
Revision 1.167 2004/07/03 11:47:04 peter
* fix rangecheck error when assigning u32bit=s32bit
Revision 1.166 2004/06/20 08:55:28 florian

View File

@ -47,6 +47,8 @@ interface
procedure release_para_temps;
procedure normal_pass_2;
procedure inlined_pass_2;
procedure pushparas;
procedure freeparas;
protected
framepointer_paraloc : tparalocation;
refcountedtemp : treference;
@ -636,6 +638,125 @@ implementation
end;
procedure tcgcallnode.pushparas;
var
ppn : tcgcallparanode;
begin
{ copy all resources to the allocated registers }
ppn:=tcgcallparanode(left);
while assigned(ppn) do
begin
if (ppn.left.nodetype<>nothingn) then
begin
{ better check for the real location of the parameter here, when stack passed parameters
are saved temporary in registers, checking for the tempparaloc.loc is wrong
}
case ppn.paraitem.paraloc[callerside].loc of
LOC_REGISTER:
begin
if not assigned(inlinecode) then
begin
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
end;
{$ifdef sparc}
case ppn.tempparaloc.size of
OS_F32 :
ppn.tempparaloc.size:=OS_32;
OS_F64 :
ppn.tempparaloc.size:=OS_64;
end;
{$endif sparc}
{$ifndef cpu64bit}
if ppn.tempparaloc.size in [OS_64,OS_S64] then
begin
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerlow,
ppn.paraitem.paraloc[callerside].registerlow);
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerhigh,
ppn.paraitem.paraloc[callerside].registerhigh);
end
else
{$endif cpu64bit}
cg.a_load_reg_reg(exprasmlist,ppn.tempparaloc.size,ppn.tempparaloc.size,
ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register);
end;
LOC_FPUREGISTER:
begin
if not assigned(inlinecode) then
begin
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
cg.a_loadfpu_reg_reg(exprasmlist,ppn.tempparaloc.size,
ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register);
end;
end;
LOC_MMREGISTER:
begin
if not assigned(inlinecode) then
begin
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
end;
cg.a_loadmm_reg_reg(exprasmlist,ppn.tempparaloc.size,
ppn.tempparaloc.size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register,mms_movescalar);
end;
LOC_REFERENCE:
begin
if not assigned(inlinecode) then
begin
{$ifdef cputargethasfixedstack}
{ copy parameters in case they were moved to a temp. location because we've a fixed stack }
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
case ppn.tempparaloc.loc of
LOC_REFERENCE:
begin
reference_reset_base(href,ppn.tempparaloc.reference.index,ppn.tempparaloc.reference.offset);
if ppn.paraitem.paraloc[callerside].size=OS_NO then
cg.a_param_copy_ref(exprasmlist,ppn.paraitem.paratype.def.size,href,ppn.paraitem.paraloc[callerside])
else
cg.a_param_ref(exprasmlist,ppn.paraitem.paraloc[callerside].size,href,ppn.paraitem.paraloc[callerside]);
end;
LOC_REGISTER:
{$ifndef cpu64bit}
if ppn.tempparaloc.size in [OS_64,OS_S64] then
cg64.a_param64_reg(exprasmlist,ppn.tempparaloc.register64,ppn.paraitem.paraloc[callerside])
else
{$endif cpu64bit}
cg.a_param_reg(exprasmlist,ppn.paraitem.paraloc[callerside].size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside]);
LOC_FPUREGISTER:
cg.a_paramfpu_reg(exprasmlist,ppn.paraitem.paraloc[callerside].size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside]);
else
internalerror(200402081);
end;
{$endif cputargethasfixedstack}
end;
end;
else
internalerror(200402091);
end;
end;
ppn:=tcgcallparanode(ppn.right);
end;
end;
procedure tcgcallnode.freeparas;
var
ppn : tcgcallparanode;
begin
{ free the resources allocated for the parameters }
ppn:=tcgcallparanode(left);
while assigned(ppn) do
begin
if not assigned(inlinecode) or
(ppn.paraitem.paraloc[callerside].loc <> LOC_REFERENCE) then
paramanager.freeparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
ppn:=tcgcallparanode(ppn.right);
end;
end;
procedure tcgcallnode.normal_pass_2;
var
regs_to_push_fpu,
@ -647,109 +768,6 @@ implementation
vmtreg : tregister;
oldaktcallnode : tcallnode;
procedure pushparas;
var
ppn : tcgcallparanode;
begin
{ copy all resources to the allocated registers }
ppn:=tcgcallparanode(left);
while assigned(ppn) do
begin
if (ppn.left.nodetype<>nothingn) then
begin
{ better check for the real location of the parameter here, when stack passed parameters
are saved temporary in registers, checking for the tempparaloc.loc is wrong
}
case ppn.paraitem.paraloc[callerside].loc of
LOC_REGISTER:
begin
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
{$ifdef sparc}
case ppn.tempparaloc.size of
OS_F32 :
ppn.tempparaloc.size:=OS_32;
OS_F64 :
ppn.tempparaloc.size:=OS_64;
end;
{$endif sparc}
{$ifndef cpu64bit}
if ppn.tempparaloc.size in [OS_64,OS_S64] then
begin
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerlow,
ppn.paraitem.paraloc[callerside].registerlow);
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerhigh,
ppn.paraitem.paraloc[callerside].registerhigh);
end
else
{$endif cpu64bit}
cg.a_load_reg_reg(exprasmlist,ppn.tempparaloc.size,ppn.tempparaloc.size,
ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register);
end;
LOC_FPUREGISTER:
begin
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
cg.a_loadfpu_reg_reg(exprasmlist,ppn.tempparaloc.size,
ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register);
end;
LOC_MMREGISTER:
begin
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
cg.a_loadmm_reg_reg(exprasmlist,ppn.tempparaloc.size,
ppn.tempparaloc.size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register,mms_movescalar);
end;
LOC_REFERENCE:
begin
{$ifdef cputargethasfixedstack}
{ copy parameters in case they were moved to a temp. location because we've a fixed stack }
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
case ppn.tempparaloc.loc of
LOC_REFERENCE:
begin
reference_reset_base(href,ppn.tempparaloc.reference.index,ppn.tempparaloc.reference.offset);
if ppn.paraitem.paraloc[callerside].size=OS_NO then
cg.a_param_copy_ref(exprasmlist,ppn.paraitem.paratype.def.size,href,ppn.paraitem.paraloc[callerside])
else
cg.a_param_ref(exprasmlist,ppn.paraitem.paraloc[callerside].size,href,ppn.paraitem.paraloc[callerside]);
end;
LOC_REGISTER:
{$ifndef cpu64bit}
if ppn.tempparaloc.size in [OS_64,OS_S64] then
cg64.a_param64_reg(exprasmlist,ppn.tempparaloc.register64,ppn.paraitem.paraloc[callerside])
else
{$endif cpu64bit}
cg.a_param_reg(exprasmlist,ppn.paraitem.paraloc[callerside].size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside]);
LOC_FPUREGISTER:
cg.a_paramfpu_reg(exprasmlist,ppn.paraitem.paraloc[callerside].size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside]);
else
internalerror(200402081);
end;
{$endif cputargethasfixedstack}
end;
else
internalerror(200402091);
end;
end;
ppn:=tcgcallparanode(ppn.right);
end;
end;
procedure freeparas;
var
ppn : tcgcallparanode;
begin
{ free the resources allocated for the parameters }
ppn:=tcgcallparanode(left);
while assigned(ppn) do
begin
paramanager.freeparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
ppn:=tcgcallparanode(ppn.right);
end;
end;
begin
if not assigned(procdefinition) or
not procdefinition.has_paraloc_info then
@ -1067,7 +1085,10 @@ implementation
oldaktcallnode:=aktcallnode;
aktcallnode:=self;
if assigned(left) then
tcallparanode(left).secondcallparan;
begin
tcallparanode(left).secondcallparan;
pushparas;
end;
aktcallnode:=oldaktcallnode;
{ create temp procinfo that will be used for the inlinecode tree }
@ -1112,6 +1133,8 @@ implementation
{$endif GDB}
gen_load_para_value(inlineentrycode);
{ now that we've loaded the para's, free them }
freeparas;
gen_initialize_code(inlineentrycode,true);
if po_assembler in current_procinfo.procdef.procoptions then
inlineentrycode.insert(Tai_marker.Create(asmblockstart));
@ -1227,7 +1250,11 @@ begin
end.
{
$Log$
Revision 1.170 2004-06-29 20:56:46 peter
Revision 1.171 2004-07-09 23:41:04 jonas
* support register parameters for inlined procedures + some inline
cleanups
Revision 1.170 2004/06/29 20:56:46 peter
* constructors don't return in parameter
Revision 1.169 2004/06/20 08:55:29 florian

View File

@ -1925,6 +1925,8 @@ implementation
var
sym : tsym;
begin
if (po_assembler in current_procinfo.procdef.procoptions) then
exit;
sym:=tsym(st.symindex.first);
while assigned(sym) do
begin
@ -1932,10 +1934,32 @@ implementation
begin
with tvarsym(sym) do
begin
{$warning TODO Allocate register paras}
{ for localloc <> LOC_REFERENCE, we need regvar support inside inlined procedures }
localloc.loc:=LOC_REFERENCE;
localloc.size:=int_cgsize(paramanager.push_size(varspez,vartype.def,pocall_inline));
tg.GetLocal(list,tcgsize2size[localloc.size],vartype.def,localloc.reference);
case paraitem.paraloc[calleeside].loc of
LOC_FPUREGISTER:
begin
paraitem.paraloc[calleeside].register := cg.getfpuregister(list,paraitem.paraloc[calleeside].size);
paraitem.paraloc[callerside] := paraitem.paraloc[calleeside];
end;
LOC_REGISTER:
begin
paraitem.paraloc[calleeside].register := cg.getintregister(list,paraitem.paraloc[calleeside].size);
paraitem.paraloc[callerside] := paraitem.paraloc[calleeside];
end;
LOC_MMREGISTER:
begin
paraitem.paraloc[calleeside].register := cg.getmmregister(list,paraitem.paraloc[calleeside].size);
paraitem.paraloc[callerside] := paraitem.paraloc[calleeside];
end;
LOC_REFERENCE:
begin
paraitem.paraloc[calleeside] := localloc;
paraitem.paraloc[callerside] := localloc;
end;
end;
if cs_asm_source in aktglobalswitches then
begin
case localloc.loc of
@ -1944,8 +1968,6 @@ implementation
std_regname(localloc.reference.index)+tostr_with_plus(localloc.reference.offset))));
end;
end;
paraitem.paraloc[callerside]:=localloc;
paraitem.paraloc[calleeside]:=localloc;
end;
end;
sym:=tsym(sym.indexnext);
@ -2067,7 +2089,11 @@ implementation
end.
{
$Log$
Revision 1.210 2004-07-04 12:24:59 jonas
Revision 1.211 2004-07-09 23:41:04 jonas
* support register parameters for inlined procedures + some inline
cleanups
Revision 1.210 2004/07/04 12:24:59 jonas
* fixed one regvar problem, but regvars are still broken since the dwarf
merge...

View File

@ -305,16 +305,21 @@ implementation
begin
case loc.loc of
LOC_REGISTER,
LOC_CREGISTER,
LOC_CREGISTER:
begin
if getsupreg(loc.register)<first_int_imreg then
cg.getexplicitregister(list,loc.register);
end;
LOC_FPUREGISTER,
LOC_CFPUREGISTER,
LOC_CFPUREGISTER:
begin
if getsupreg(loc.register)<first_fpu_imreg then
cg.getexplicitregister(list,loc.register);
end;
LOC_MMREGISTER,
LOC_CMMREGISTER :
begin
{ NR_NO means we don't need to allocate the parameter.
This is used for inlining parameters which allocates
the parameters in gen_alloc_parast (PFV) }
if loc.register<>NR_NO then
if getsupreg(loc.register)<first_mm_imreg then
cg.getexplicitregister(list,loc.register);
end;
LOC_REFERENCE,
@ -495,40 +500,10 @@ implementation
function tparamanager.create_inline_paraloc_info(p : tabstractprocdef):longint;
var
hp : tparaitem;
paraloc : tparalocation;
parasize : longint;
begin
parasize:=0;
hp:=tparaitem(p.para.first);
while assigned(hp) do
begin
if push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption) then
paraloc.size:=OS_ADDR
else
paraloc.size:=def_cgsize(hp.paratype.def);
if paraloc.size=OS_NO then
internalerror(200309301);
{ Indicate parameter is loaded in register, the register
will be allocated when the allocpara is called }
paraloc.loc:=LOC_REGISTER;
paraloc.register:=NR_NO;
(*
paraloc.loc:=LOC_REFERENCE;
paraloc.reference.index:=NR_FRAME_POINTER_REG;
l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
varalign:=size_2_align(l);
paraloc.reference.offset:=parasize+target_info.first_parm_offset;
varalign:=used_align(varalign,p.paraalign,p.paraalign);
parasize:=align(parasize+l,varalign);
*)
hp.paraloc[callerside]:=paraloc;
hp.paraloc[calleeside]:=paraloc;
hp:=tparaitem(hp.next);
end;
{ We need to return the size allocated }
result:=parasize;
create_paraloc_info(p,callerside);
result:=create_paraloc_info(p,calleeside);
end;
@ -540,7 +515,11 @@ end.
{
$Log$
Revision 1.76 2004-06-20 08:55:30 florian
Revision 1.77 2004-07-09 23:41:04 jonas
* support register parameters for inlined procedures + some inline
cleanups
Revision 1.76 2004/06/20 08:55:30 florian
* logs truncated
Revision 1.75 2004/06/16 20:07:09 florian