Browse Source

* 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 -

sergei 12 năm trước cách đây
mục cha
commit
354ebb822a
3 tập tin đã thay đổi với 28 bổ sung9 xóa
  1. 20 2
      compiler/mips/cgcpu.pas
  2. 0 4
      compiler/mips/cpupara.pas
  3. 8 3
      compiler/mips/cpupi.pas

+ 20 - 2
compiler/mips/cgcpu.pas

@@ -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

+ 0 - 4
compiler/mips/cpupara.pas

@@ -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;
 

+ 8 - 3
compiler/mips/cpupi.pas

@@ -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;