* push_addr_param must be defined per target

This commit is contained in:
peter 2005-02-03 20:04:49 +00:00
parent c55c88db32
commit 18ebd28692
6 changed files with 154 additions and 92 deletions

View File

@ -159,12 +159,15 @@ unit cpupara;
function tarmparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
begin
result:=false;
if varspez in [vs_var,vs_out] then
begin
result:=true;
exit;
end;
case def.deftype of
variantdef,
formaldef,
recorddef:
result:=true;
arraydef:
@ -172,14 +175,14 @@ unit cpupara;
is_open_array(def) or
is_array_of_const(def) or
is_array_constructor(def);
objectdef :
result:=is_object(def);
setdef :
result:=(tsetdef(def).settype<>smallset);
stringdef :
result:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
procvardef :
result:=po_methodpointer in tprocvardef(def).procoptions;
else
result:=inherited push_addr_param(varspez,def,calloption);
end;
end;
@ -446,7 +449,10 @@ begin
end.
{
$Log$
Revision 1.29 2005-01-15 21:45:35 florian
Revision 1.30 2005-02-03 20:04:49 peter
* push_addr_param must be defined per target
Revision 1.29 2005/01/15 21:45:35 florian
* arm compiler fixed
Revision 1.28 2005/01/01 19:30:17 florian

View File

@ -84,7 +84,10 @@ unit cpupara;
while assigned(paraloc) do
begin
if (paraloc^.loc<>LOC_REFERENCE) then
result:=false;
begin
result:=false;
exit;
end;
paraloc:=paraloc^.next;
end;
end;
@ -116,38 +119,63 @@ unit cpupara;
function ti386paramanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
begin
case target_info.system of
system_i386_win32 :
result:=false;
{ var,out always require address }
if varspez in [vs_var,vs_out] then
begin
result:=true;
exit;
end;
{ Only vs_const, vs_value here }
case def.deftype of
variantdef,
formaldef :
result:=true;
recorddef :
begin
case def.deftype of
recorddef :
begin
{ Win32 passes small records on the stack for call by
value }
if (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
(varspez=vs_value) and
(def.size<=8) then
begin
result:=false;
exit;
end;
end;
arraydef :
begin
{ Win32 passes arrays on the stack for call by
value }
if (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
(varspez=vs_value) and
(tarraydef(def).highrange>=tarraydef(def).lowrange) then
begin
result:=false;
exit;
end;
end;
end;
{ Win32 passes small records on the stack for call by
value }
if (target_info.system=system_i386_win32) and
(calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
(varspez=vs_value) and
(def.size<=8) then
result:=false
else
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (def.size>sizeof(aint));
end;
arraydef :
begin
{ Win32 passes arrays on the stack for call by
value }
if (target_info.system=system_i386_win32) and
(calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
(varspez=vs_value) and
(tarraydef(def).highrange>=tarraydef(def).lowrange) then
result:=false
else
{ array of const values are pushed on the stack }
if (calloption in [pocall_cdecl,pocall_cppdecl]) then
result:=not is_array_of_const(def)
else
begin
result:=(
(tarraydef(def).highrange>=tarraydef(def).lowrange) and
(def.size>sizeof(aint))
) or
is_open_array(def) or
is_array_of_const(def) or
is_array_constructor(def);
end;
end;
objectdef :
result:=is_object(def);
stringdef :
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tstringdef(def).string_typ in [st_shortstring,st_longstring]);
procvardef :
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (po_methodpointer in tprocvardef(def).procoptions);
setdef :
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tsetdef(def).settype<>smallset);
end;
result:=inherited push_addr_param(varspez,def,calloption);
end;
@ -602,7 +630,10 @@ begin
end.
{
$Log$
Revision 1.64 2005-01-30 11:03:22 peter
Revision 1.65 2005-02-03 20:04:49 peter
* push_addr_param must be defined per target
Revision 1.64 2005/01/30 11:03:22 peter
* revert last commit
Revision 1.62 2005/01/18 22:19:20 peter

View File

@ -52,7 +52,7 @@ unit paramgr;
{ Returns true if a parameter is too large to copy and only
the address is pushed
}
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;virtual;
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;virtual;abstract;
{ return the size of a push }
function push_size(varspez:tvarspez;def : tdef;calloption : tproccalloption) : longint;
{# Returns a structure giving the information on
@ -157,53 +157,6 @@ implementation
end;
{ true if a parameter is too large to copy and only the address is pushed }
function tparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
begin
result:=false;
{ var,out always require address }
if varspez in [vs_var,vs_out] then
begin
result:=true;
exit;
end;
{ Only vs_const, vs_value here }
case def.deftype of
variantdef,
formaldef :
result:=true;
recorddef :
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (def.size>sizeof(aint));
arraydef :
begin
if (calloption in [pocall_cdecl,pocall_cppdecl]) then
begin
{ array of const values are pushed on the stack }
result:=not is_array_of_const(def);
end
else
begin
result:=(
(tarraydef(def).highrange>=tarraydef(def).lowrange) and
(def.size>sizeof(aint))
) or
is_open_array(def) or
is_array_of_const(def) or
is_array_constructor(def);
end;
end;
objectdef :
result:=is_object(def);
stringdef :
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tstringdef(def).string_typ in [st_shortstring,st_longstring]);
procvardef :
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (po_methodpointer in tprocvardef(def).procoptions);
setdef :
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tsetdef(def).settype<>smallset);
end;
end;
{ return the size of a push }
function tparamanager.push_size(varspez:tvarspez;def : tdef;calloption : tproccalloption) : longint;
begin
@ -433,7 +386,10 @@ end.
{
$Log$
Revision 1.85 2005-01-20 17:47:01 peter
Revision 1.86 2005-02-03 20:04:49 peter
* push_addr_param must be defined per target
Revision 1.85 2005/01/20 17:47:01 peter
* remove copy_value_on_stack and a_param_copy_ref
Revision 1.84 2005/01/18 22:19:20 peter

View File

@ -173,6 +173,7 @@ unit cpupara;
function tppcparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
begin
result:=false;
{ var,out always require address }
if varspez in [vs_var,vs_out] then
begin
@ -180,6 +181,9 @@ unit cpupara;
exit;
end;
case def.deftype of
variantdef,
formaldef :
result:=true;
recorddef:
result :=(target_info.abi<>abi_powerpc_aix);
arraydef:
@ -187,14 +191,14 @@ unit cpupara;
is_open_array(def) or
is_array_of_const(def) or
is_array_constructor(def);
objectdef :
result:=is_object(def);
setdef :
result:=(tsetdef(def).settype<>smallset);
stringdef :
result:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
procvardef :
result:=po_methodpointer in tprocvardef(def).procoptions;
else
result:=inherited push_addr_param(varspez,def,calloption);
end;
end;
@ -645,7 +649,10 @@ begin
end.
{
$Log$
Revision 1.86 2005-01-31 17:46:25 peter
Revision 1.87 2005-02-03 20:04:49 peter
* push_addr_param must be defined per target
Revision 1.86 2005/01/31 17:46:25 peter
* fixed parseparaloc
Revision 1.85 2005/01/20 17:47:01 peter

View File

@ -162,7 +162,7 @@ cat <<EOFCFG > $thefile
#-Cr
#-Ct
# Optimizer switches
# Optimizer switches for i386 compiler
# -Og generate smaller code
# -OG generate faster code (default)
# -Or keep certain variables in registers (still BUGGY!!!)

View File

@ -40,6 +40,8 @@ unit cpupara;
procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;paras:tparalist;
var intparareg,mmparareg,parasize:longint);
public
function param_use_paraloc(const cgpara:tcgpara):boolean;override;
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
procedure getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);override;
function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
@ -140,6 +142,66 @@ unit cpupara;
end;
function tx86_64paramanager.param_use_paraloc(const cgpara:tcgpara):boolean;
var
paraloc : pcgparalocation;
begin
if not assigned(cgpara.location) then
internalerror(200410102);
result:=true;
{ All locations are LOC_REFERENCE }
paraloc:=cgpara.location;
while assigned(paraloc) do
begin
if (paraloc^.loc<>LOC_REFERENCE) then
begin
result:=false;
exit;
end;
paraloc:=paraloc^.next;
end;
end;
{ true if a parameter is too large to copy and only the address is pushed }
function tx86_64paramanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
begin
result:=false;
{ var,out always require address }
if varspez in [vs_var,vs_out] then
begin
result:=true;
exit;
end;
{ Only vs_const, vs_value here }
case def.deftype of
variantdef,
formaldef :
result:=true;
recorddef :
result:=(def.size>sizeof(aint));
arraydef :
begin
result:=(
(tarraydef(def).highrange>=tarraydef(def).lowrange) and
(def.size>sizeof(aint))
) or
is_open_array(def) or
is_array_of_const(def) or
is_array_constructor(def);
end;
objectdef :
result:=is_object(def);
stringdef :
result:=(tstringdef(def).string_typ in [st_shortstring,st_longstring]);
procvardef :
result:=(po_methodpointer in tprocvardef(def).procoptions);
setdef :
result:=(tsetdef(def).settype<>smallset);
end;
end;
function tx86_64paramanager.get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;
begin
result:=[RS_RAX,RS_RCX,RS_RDX,RS_RSI,RS_RDI,RS_R8,RS_R9,RS_R10,RS_R11];
@ -350,10 +412,7 @@ unit cpupara;
end
else
begin
if (paralen<=sizeof(aint)) then
l:=paralen
else
l:=sizeof(aint);
l:=paralen;
paraloc^.size:=int_cgsize(l);
end;
if side=callerside then
@ -433,7 +492,10 @@ begin
end.
{
$Log$
Revision 1.15 2005-02-03 18:32:25 peter
Revision 1.16 2005-02-03 20:04:49 peter
* push_addr_param must be defined per target
Revision 1.15 2005/02/03 18:32:25 peter
* fix extended paraloc
Revision 1.14 2005/01/29 11:36:52 peter