mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 00:09:26 +02:00
* cleanup x86_64 structures in registers
git-svn-id: trunk@8214 -
This commit is contained in:
parent
ea61793ca2
commit
4e6c57b9ee
@ -65,7 +65,18 @@ unit cpupara;
|
|||||||
paraintsupregs_winx64 : array[0..3] of tsuperregister = (RS_RCX,RS_RDX,RS_R8,RS_R9);
|
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);
|
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
|
begin
|
||||||
loc1:=LOC_INVALID;
|
loc1:=LOC_INVALID;
|
||||||
loc2:=LOC_INVALID;
|
loc2:=LOC_INVALID;
|
||||||
@ -96,11 +107,12 @@ unit cpupara;
|
|||||||
end;
|
end;
|
||||||
recorddef:
|
recorddef:
|
||||||
begin
|
begin
|
||||||
{ win64 abi }
|
if structure_in_registers(varspez,p.size) then
|
||||||
if ((target_info.system=system_x86_64_win64) and (p.size<=8)) or
|
begin
|
||||||
{ linux abi }
|
loc1:=LOC_REGISTER;
|
||||||
((target_info.system<>system_x86_64_win64) and (p.size<=16)) then
|
if p.size>8 then
|
||||||
loc1:=LOC_REGISTER
|
loc2:=LOC_REGISTER;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
loc1:=LOC_REFERENCE;
|
loc1:=LOC_REFERENCE;
|
||||||
end;
|
end;
|
||||||
@ -108,10 +120,7 @@ unit cpupara;
|
|||||||
begin
|
begin
|
||||||
if is_object(p) then
|
if is_object(p) then
|
||||||
begin
|
begin
|
||||||
{ win64 abi }
|
if structure_in_registers(varspez,p.size) then
|
||||||
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
|
loc1:=LOC_REGISTER
|
||||||
else
|
else
|
||||||
loc1:=LOC_REFERENCE;
|
loc1:=LOC_REFERENCE;
|
||||||
@ -122,13 +131,12 @@ unit cpupara;
|
|||||||
arraydef:
|
arraydef:
|
||||||
begin
|
begin
|
||||||
if not(is_special_array(p)) and
|
if not(is_special_array(p)) and
|
||||||
(
|
structure_in_registers(varspez,p.size) then
|
||||||
{ win64 abi }
|
begin
|
||||||
((target_info.system=system_x86_64_win64) and (p.size<=8)) or
|
loc1:=LOC_REGISTER;
|
||||||
{ linux abi }
|
if p.size>8 then
|
||||||
((target_info.system<>system_x86_64_win64) and (p.size<=16))
|
loc2:=LOC_REGISTER;
|
||||||
) then
|
end
|
||||||
loc1:=LOC_REGISTER
|
|
||||||
else
|
else
|
||||||
loc1:=LOC_REFERENCE;
|
loc1:=LOC_REFERENCE;
|
||||||
end;
|
end;
|
||||||
@ -142,11 +150,12 @@ unit cpupara;
|
|||||||
if is_shortstring(p) or is_longstring(p) then
|
if is_shortstring(p) or is_longstring(p) then
|
||||||
begin
|
begin
|
||||||
{ handle long and shortstrings like arrays }
|
{ handle long and shortstrings like arrays }
|
||||||
{ win64 abi }
|
if structure_in_registers(varspez,p.size) then
|
||||||
if ((target_info.system=system_x86_64_win64) and (p.size<=8)) or
|
begin
|
||||||
{ linux abi }
|
loc1:=LOC_REGISTER;
|
||||||
((target_info.system<>system_x86_64_win64) and (p.size<=16)) then
|
if p.size>8 then
|
||||||
loc1:=LOC_REGISTER
|
loc2:=LOC_REGISTER;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
loc1:=LOC_REFERENCE;
|
loc1:=LOC_REFERENCE;
|
||||||
end
|
end
|
||||||
@ -159,12 +168,17 @@ unit cpupara;
|
|||||||
loc1:=LOC_REFERENCE;
|
loc1:=LOC_REFERENCE;
|
||||||
procvardef:
|
procvardef:
|
||||||
begin
|
begin
|
||||||
{ This is a record < 16 bytes }
|
|
||||||
if (po_methodpointer in tprocvardef(p).procoptions) then
|
if (po_methodpointer in tprocvardef(p).procoptions) then
|
||||||
|
begin
|
||||||
|
{ This is a record of 16 bytes }
|
||||||
|
if structure_in_registers(varspez,p.size) then
|
||||||
begin
|
begin
|
||||||
loc1:=LOC_REGISTER;
|
loc1:=LOC_REGISTER;
|
||||||
loc2:=LOC_REGISTER;
|
loc2:=LOC_REGISTER;
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
loc1:=LOC_REFERENCE;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
loc1:=LOC_REGISTER;
|
loc1:=LOC_REGISTER;
|
||||||
end;
|
end;
|
||||||
@ -224,8 +238,7 @@ unit cpupara;
|
|||||||
formaldef :
|
formaldef :
|
||||||
result:=true;
|
result:=true;
|
||||||
recorddef :
|
recorddef :
|
||||||
result:=((varspez=vs_const) and ((def.size>16) or (calloption<>pocall_register))) or
|
result:=not structure_in_registers(varspez,def.size);
|
||||||
((target_info.system=system_x86_64_win64) and (def.size>8));
|
|
||||||
arraydef :
|
arraydef :
|
||||||
begin
|
begin
|
||||||
result:=not(
|
result:=not(
|
||||||
@ -237,11 +250,20 @@ unit cpupara;
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
objectdef :
|
objectdef :
|
||||||
result:=is_object(def);
|
begin
|
||||||
|
if is_object(def) then
|
||||||
|
result:=not structure_in_registers(varspez,def.size);
|
||||||
|
end;
|
||||||
stringdef :
|
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 :
|
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 :
|
setdef :
|
||||||
result:=(tsetdef(def).settype<>smallset);
|
result:=(tsetdef(def).settype<>smallset);
|
||||||
end;
|
end;
|
||||||
@ -408,7 +430,7 @@ unit cpupara;
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
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);
|
paralen:=push_size(hp.varspez,hp.vardef,p.proccalloption);
|
||||||
paracgsize:=def_cgsize(hp.vardef);
|
paracgsize:=def_cgsize(hp.vardef);
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user