mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2026-01-06 11:30:44 +01:00
* fixed internalerrors on non-use_fixed_stack platforms after r16050:
stack parameters can also be split over multiple locations git-svn-id: trunk@16052 -
This commit is contained in:
parent
92901a0619
commit
6094cb79dc
@ -485,7 +485,7 @@ implementation
|
||||
href : treference;
|
||||
calleralignment,
|
||||
tmpalignment: longint;
|
||||
skipmemloc: boolean;
|
||||
skipiffinalloc: boolean;
|
||||
begin
|
||||
{ copy all resources to the allocated registers }
|
||||
ppn:=tcgcallparanode(left);
|
||||
@ -505,10 +505,9 @@ implementation
|
||||
(calleralignment=0) then
|
||||
internalerror(2009020701);
|
||||
callerparaloc:=ppn.parasym.paraloc[callerside].location;
|
||||
skipmemloc:=
|
||||
(not paramanager.use_fixed_stack or
|
||||
not(ppn.followed_by_stack_tainting_call_cached)) and
|
||||
paramanager.is_simple_stack_paraloc(callerparaloc);
|
||||
skipiffinalloc:=
|
||||
not paramanager.use_fixed_stack or
|
||||
not(ppn.followed_by_stack_tainting_call_cached);
|
||||
while assigned(callerparaloc) do
|
||||
begin
|
||||
{ Every paraloc must have a matching tmpparaloc }
|
||||
@ -545,7 +544,8 @@ implementation
|
||||
end;
|
||||
LOC_REFERENCE:
|
||||
begin
|
||||
if not skipmemloc then
|
||||
if skipiffinalloc and
|
||||
paramanager.is_stack_paraloc(callerparaloc) then
|
||||
begin
|
||||
{ Can't have a data copied to the stack, every location
|
||||
must contain a valid size field }
|
||||
|
||||
@ -124,8 +124,9 @@ unit paramgr;
|
||||
}
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;virtual;abstract;
|
||||
|
||||
function is_simple_stack_paraloc(paraloc: pcgparalocation): boolean;
|
||||
function is_stack_paraloc(paraloc: pcgparalocation): boolean;
|
||||
procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);virtual;
|
||||
procedure duplicatecgparaloc(const orgparaloc: pcgparalocation; intonewparaloc: pcgparalocation);
|
||||
procedure duplicateparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);
|
||||
|
||||
function parseparaloc(parasym : tparavarsym;const s : string) : boolean;virtual;
|
||||
@ -327,13 +328,12 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tparamanager.is_simple_stack_paraloc(paraloc: pcgparalocation): boolean;
|
||||
function tparamanager.is_stack_paraloc(paraloc: pcgparalocation): boolean;
|
||||
begin
|
||||
result:=
|
||||
assigned(paraloc) and
|
||||
(paraloc^.loc=LOC_REFERENCE) and
|
||||
(paraloc^.reference.index=NR_STACK_POINTER_REG) and
|
||||
not assigned(paraloc^.next);
|
||||
(paraloc^.reference.index=NR_STACK_POINTER_REG);
|
||||
end;
|
||||
|
||||
|
||||
@ -345,13 +345,6 @@ implementation
|
||||
newparaloc : pcgparalocation;
|
||||
begin
|
||||
paraloc:=parasym.paraloc[callerside].location;
|
||||
if can_use_final_stack_loc and
|
||||
is_simple_stack_paraloc(paraloc) then
|
||||
begin
|
||||
duplicateparaloc(list,calloption,parasym,cgpara);
|
||||
exit;
|
||||
end;
|
||||
|
||||
cgpara.reset;
|
||||
cgpara.size:=parasym.paraloc[callerside].size;
|
||||
cgpara.intsize:=parasym.paraloc[callerside].intsize;
|
||||
@ -372,7 +365,9 @@ implementation
|
||||
i386 isn't affected anyways because it uses the stack to push parameters
|
||||
on arm it reduces executable size of the compiler by 2.1 per cent (FK) }
|
||||
{ Does it fit a register? }
|
||||
if (len<=sizeof(pint)) and
|
||||
if (not can_use_final_stack_loc or
|
||||
not is_stack_paraloc(paraloc)) and
|
||||
(len<=sizeof(pint)) and
|
||||
(paraloc^.size in [OS_8,OS_16,OS_32,OS_64,OS_128,OS_S8,OS_S16,OS_S32,OS_S64,OS_S128]) then
|
||||
newparaloc^.loc:=LOC_REGISTER
|
||||
else
|
||||
@ -386,9 +381,15 @@ implementation
|
||||
newparaloc^.register:=cg.getmmregister(list,paraloc^.size);
|
||||
LOC_REFERENCE :
|
||||
begin
|
||||
tg.gettemp(list,len,cgpara.alignment,tt_persistent,href);
|
||||
newparaloc^.reference.index:=href.base;
|
||||
newparaloc^.reference.offset:=href.offset;
|
||||
if can_use_final_stack_loc and
|
||||
is_stack_paraloc(paraloc) then
|
||||
duplicatecgparaloc(paraloc,newparaloc)
|
||||
else
|
||||
begin
|
||||
tg.gettemp(list,len,cgpara.alignment,tt_persistent,href);
|
||||
newparaloc^.reference.index:=href.base;
|
||||
newparaloc^.reference.offset:=href.offset;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
paraloc:=paraloc^.next;
|
||||
@ -396,6 +397,13 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tparamanager.duplicatecgparaloc(const orgparaloc: pcgparalocation; intonewparaloc: pcgparalocation);
|
||||
begin
|
||||
move(orgparaloc^,intonewparaloc^,sizeof(intonewparaloc^));
|
||||
intonewparaloc^.next:=nil;
|
||||
end;
|
||||
|
||||
|
||||
procedure tparamanager.duplicateparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);
|
||||
var
|
||||
paraloc,
|
||||
@ -412,8 +420,7 @@ implementation
|
||||
while assigned(paraloc) do
|
||||
begin
|
||||
newparaloc:=cgpara.add_location;
|
||||
move(paraloc^,newparaloc^,sizeof(newparaloc^));
|
||||
newparaloc^.next:=nil;
|
||||
duplicatecgparaloc(paraloc,newparaloc);
|
||||
paraloc:=paraloc^.next;
|
||||
end;
|
||||
end;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user