* cleanup x86_64 structures in registers

git-svn-id: trunk@8214 -
This commit is contained in:
peter 2007-08-02 20:46:48 +00:00
parent ea61793ca2
commit 4e6c57b9ee

View File

@ -65,7 +65,18 @@ unit cpupara;
paraintsupregs_winx64 : array[0..3] of tsuperregister = (RS_RCX,RS_RDX,RS_R8,RS_R9);
parammsupregs_winx64 : array[0..3] of tsuperregister = (RS_XMM0,RS_XMM1,RS_XMM2,RS_XMM3);
procedure getvalueparaloc(p : tdef;var loc1,loc2:tcgloc);
function structure_in_registers(varspez:tvarspez;size:longint):boolean;
begin
if (target_info.system=system_x86_64_win64) then
{$warning Temporary hack: vs_const parameters are always passed by reference for win64}
result:=(varspez=vs_value) and (size in [1,2,4,8])
else
result:=(size<=16);
end;
procedure getvalueparaloc(varspez:tvarspez;p : tdef;var loc1,loc2:tcgloc);
begin
loc1:=LOC_INVALID;
loc2:=LOC_INVALID;
@ -96,11 +107,12 @@ unit cpupara;
end;
recorddef:
begin
{ win64 abi }
if ((target_info.system=system_x86_64_win64) and (p.size<=8)) or
{ linux abi }
((target_info.system<>system_x86_64_win64) and (p.size<=16)) then
loc1:=LOC_REGISTER
if structure_in_registers(varspez,p.size) then
begin
loc1:=LOC_REGISTER;
if p.size>8 then
loc2:=LOC_REGISTER;
end
else
loc1:=LOC_REFERENCE;
end;
@ -108,10 +120,7 @@ unit cpupara;
begin
if is_object(p) then
begin
{ win64 abi }
if ((target_info.system=system_x86_64_win64) and (p.size<=8)) or
{ linux abi }
((target_info.system<>system_x86_64_win64) and (p.size<=16)) then
if structure_in_registers(varspez,p.size) then
loc1:=LOC_REGISTER
else
loc1:=LOC_REFERENCE;
@ -122,13 +131,12 @@ unit cpupara;
arraydef:
begin
if not(is_special_array(p)) and
(
{ win64 abi }
((target_info.system=system_x86_64_win64) and (p.size<=8)) or
{ linux abi }
((target_info.system<>system_x86_64_win64) and (p.size<=16))
) then
loc1:=LOC_REGISTER
structure_in_registers(varspez,p.size) then
begin
loc1:=LOC_REGISTER;
if p.size>8 then
loc2:=LOC_REGISTER;
end
else
loc1:=LOC_REFERENCE;
end;
@ -142,11 +150,12 @@ unit cpupara;
if is_shortstring(p) or is_longstring(p) then
begin
{ handle long and shortstrings like arrays }
{ win64 abi }
if ((target_info.system=system_x86_64_win64) and (p.size<=8)) or
{ linux abi }
((target_info.system<>system_x86_64_win64) and (p.size<=16)) then
loc1:=LOC_REGISTER
if structure_in_registers(varspez,p.size) then
begin
loc1:=LOC_REGISTER;
if p.size>8 then
loc2:=LOC_REGISTER;
end
else
loc1:=LOC_REFERENCE;
end
@ -159,11 +168,16 @@ unit cpupara;
loc1:=LOC_REFERENCE;
procvardef:
begin
{ This is a record < 16 bytes }
if (po_methodpointer in tprocvardef(p).procoptions) then
begin
loc1:=LOC_REGISTER;
loc2:=LOC_REGISTER;
{ This is a record of 16 bytes }
if structure_in_registers(varspez,p.size) then
begin
loc1:=LOC_REGISTER;
loc2:=LOC_REGISTER;
end
else
loc1:=LOC_REFERENCE;
end
else
loc1:=LOC_REGISTER;
@ -224,8 +238,7 @@ unit cpupara;
formaldef :
result:=true;
recorddef :
result:=((varspez=vs_const) and ((def.size>16) or (calloption<>pocall_register))) or
((target_info.system=system_x86_64_win64) and (def.size>8));
result:=not structure_in_registers(varspez,def.size);
arraydef :
begin
result:=not(
@ -237,11 +250,20 @@ unit cpupara;
);
end;
objectdef :
result:=is_object(def);
begin
if is_object(def) then
result:=not structure_in_registers(varspez,def.size);
end;
stringdef :
result:=(tstringdef(def).stringtype in [st_shortstring,st_longstring]);
begin
if (tstringdef(def).stringtype in [st_shortstring,st_longstring]) then
result:=not structure_in_registers(varspez,def.size);
end;
procvardef :
result:=(po_methodpointer in tprocvardef(def).procoptions) and (target_info.system=system_x86_64_win64);
begin
if (po_methodpointer in tprocvardef(def).procoptions) then
result:=not structure_in_registers(varspez,def.size);
end;
setdef :
result:=(tsetdef(def).settype<>smallset);
end;
@ -408,7 +430,7 @@ unit cpupara;
end
else
begin
getvalueparaloc(hp.vardef,loc[1],loc[2]);
getvalueparaloc(hp.varspez,hp.vardef,loc[1],loc[2]);
paralen:=push_size(hp.varspez,hp.vardef,p.proccalloption);
paracgsize:=def_cgsize(hp.vardef);
end;