mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 15:09:20 +02:00
* MIPS: fixed layout of stack frame in case procedure does only low-level calls (via a_call_name, etc.). A 16-byte outgoing parameter area must be allocated regardless of actual parameter count.
* Abort if attempting to emit a call without pi_do_call flag set, because the outgoing parameter area determines layout of temps and therefore cannot be created/changed during pass 2. * Bypass g_concatcopy_move if procedure is a leaf one, due to the restriction mentioned above. git-svn-id: trunk@23644 -
This commit is contained in:
parent
5d5d226487
commit
354ebb822a
@ -611,6 +611,10 @@ procedure TCGMIPS.a_call_name(list: tasmlist; const s: string; weak: boolean);
|
|||||||
var
|
var
|
||||||
href: treference;
|
href: treference;
|
||||||
begin
|
begin
|
||||||
|
if assigned(current_procinfo) and
|
||||||
|
not (pi_do_call in current_procinfo.flags) then
|
||||||
|
InternalError(2013022101);
|
||||||
|
|
||||||
if (cs_create_pic in current_settings.moduleswitches) then
|
if (cs_create_pic in current_settings.moduleswitches) then
|
||||||
begin
|
begin
|
||||||
reference_reset(href,sizeof(aint));
|
reference_reset(href,sizeof(aint));
|
||||||
@ -643,6 +647,9 @@ end;
|
|||||||
|
|
||||||
procedure TCGMIPS.a_call_reg(list: tasmlist; Reg: TRegister);
|
procedure TCGMIPS.a_call_reg(list: tasmlist; Reg: TRegister);
|
||||||
begin
|
begin
|
||||||
|
if assigned(current_procinfo) and
|
||||||
|
not (pi_do_call in current_procinfo.flags) then
|
||||||
|
InternalError(2013022102);
|
||||||
if (cs_create_pic in current_settings.moduleswitches) then
|
if (cs_create_pic in current_settings.moduleswitches) then
|
||||||
begin
|
begin
|
||||||
if (Reg <> NR_PIC_FUNC) then
|
if (Reg <> NR_PIC_FUNC) then
|
||||||
@ -1690,8 +1697,16 @@ var
|
|||||||
begin
|
begin
|
||||||
if len > high(longint) then
|
if len > high(longint) then
|
||||||
internalerror(2002072704);
|
internalerror(2002072704);
|
||||||
|
{ A call (to FPC_MOVE) requires the outgoing parameter area to be properly
|
||||||
|
allocated on stack. This can only be done before tmipsprocinfo.set_first_temp_offset,
|
||||||
|
i.e. before secondpass. Other internal procedures request correct stack frame
|
||||||
|
by setting pi_do_call during firstpass, but for this particular one it is impossible.
|
||||||
|
Therefore, if the current procedure is a leaf one, we have to leave it that way. }
|
||||||
|
|
||||||
{ anybody wants to determine a good value here :)? }
|
{ anybody wants to determine a good value here :)? }
|
||||||
if len > 100 then
|
if (len > 100) and
|
||||||
|
assigned(current_procinfo) and
|
||||||
|
(pi_do_call in current_procinfo.flags) then
|
||||||
g_concatcopy_move(list, Source, dest, len)
|
g_concatcopy_move(list, Source, dest, len)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -1789,7 +1804,10 @@ var
|
|||||||
lab: tasmlabel;
|
lab: tasmlabel;
|
||||||
ai : TaiCpu;
|
ai : TaiCpu;
|
||||||
begin
|
begin
|
||||||
if len > 31 then
|
if (len > 31) and
|
||||||
|
{ see comment in g_concatcopy }
|
||||||
|
assigned(current_procinfo) and
|
||||||
|
(pi_do_call in current_procinfo.flags) then
|
||||||
g_concatcopy_move(list, Source, dest, len)
|
g_concatcopy_move(list, Source, dest, len)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
@ -155,10 +155,6 @@ implementation
|
|||||||
reference.offset:=nr*mips_sizeof_register_param;
|
reference.offset:=nr*mips_sizeof_register_param;
|
||||||
end;
|
end;
|
||||||
size:=OS_INT;
|
size:=OS_INT;
|
||||||
{ Be sure to reserve enough stack space tp cope with
|
|
||||||
that parameter }
|
|
||||||
if assigned(current_procinfo) then
|
|
||||||
TMIPSProcinfo(current_procinfo).allocate_push_parasize((nr+1)*mips_sizeof_register_param);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -69,6 +69,9 @@ implementation
|
|||||||
i : longint;
|
i : longint;
|
||||||
begin
|
begin
|
||||||
inherited create(aparent);
|
inherited create(aparent);
|
||||||
|
{ will call _mcount if profiling }
|
||||||
|
if cs_profile in current_settings.moduleswitches then
|
||||||
|
include(flags,pi_do_call);
|
||||||
for i:=low(tparasupregs) to high(tparasupregs) do
|
for i:=low(tparasupregs) to high(tparasupregs) do
|
||||||
begin
|
begin
|
||||||
register_used[i]:=false;
|
register_used[i]:=false;
|
||||||
@ -102,6 +105,11 @@ implementation
|
|||||||
tg.setfirsttemp(0)
|
tg.setfirsttemp(0)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
{ Fixes the case when there are calls done by low-level means
|
||||||
|
(cg.a_call_name) but no child callnode }
|
||||||
|
if (pi_do_call in flags) then
|
||||||
|
allocate_push_parasize(mips_nb_used_registers*sizeof(aint));
|
||||||
|
|
||||||
if not (po_nostackframe in procdef.procoptions) then
|
if not (po_nostackframe in procdef.procoptions) then
|
||||||
tg.setfirsttemp(Align(maxpushedparasize+
|
tg.setfirsttemp(Align(maxpushedparasize+
|
||||||
floatregssave*sizeof(aint)+intregssave*sizeof(aint)
|
floatregssave*sizeof(aint)+intregssave*sizeof(aint)
|
||||||
@ -113,9 +121,6 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
function TMIPSProcInfo.calc_stackframe_size:longint;
|
function TMIPSProcInfo.calc_stackframe_size:longint;
|
||||||
var
|
|
||||||
r : byte;
|
|
||||||
regs: tcpuregisterset;
|
|
||||||
begin
|
begin
|
||||||
result:=maxpushedparasize;
|
result:=maxpushedparasize;
|
||||||
floatregstart:=result;
|
floatregstart:=result;
|
||||||
|
Loading…
Reference in New Issue
Block a user