* 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:
sergei 2013-02-21 20:57:38 +00:00
parent 5d5d226487
commit 354ebb822a
3 changed files with 28 additions and 9 deletions

View File

@ -611,6 +611,10 @@ procedure TCGMIPS.a_call_name(list: tasmlist; const s: string; weak: boolean);
var
href: treference;
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
begin
reference_reset(href,sizeof(aint));
@ -643,6 +647,9 @@ end;
procedure TCGMIPS.a_call_reg(list: tasmlist; Reg: TRegister);
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
begin
if (Reg <> NR_PIC_FUNC) then
@ -1690,8 +1697,16 @@ var
begin
if len > high(longint) then
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 :)? }
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)
else
begin
@ -1789,7 +1804,10 @@ var
lab: tasmlabel;
ai : TaiCpu;
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)
else
begin

View File

@ -155,10 +155,6 @@ implementation
reference.offset:=nr*mips_sizeof_register_param;
end;
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;

View File

@ -69,6 +69,9 @@ implementation
i : longint;
begin
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
begin
register_used[i]:=false;
@ -102,6 +105,11 @@ implementation
tg.setfirsttemp(0)
else
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
tg.setfirsttemp(Align(maxpushedparasize+
floatregssave*sizeof(aint)+intregssave*sizeof(aint)
@ -113,9 +121,6 @@ implementation
function TMIPSProcInfo.calc_stackframe_size:longint;
var
r : byte;
regs: tcpuregisterset;
begin
result:=maxpushedparasize;
floatregstart:=result;