Bladeren bron

* better calculation of estimated stack frame size

git-svn-id: trunk@46733 -
florian 4 jaren geleden
bovenliggende
commit
b36597c76a
5 gewijzigde bestanden met toevoegingen van 66 en 12 verwijderingen
  1. 4 0
      compiler/ncal.pas
  2. 2 0
      compiler/nld.pas
  3. 9 1
      compiler/xtensa/cgcpu.pas
  4. 38 2
      compiler/xtensa/cpupara.pas
  5. 13 9
      compiler/xtensa/cpupi.pas

+ 4 - 0
compiler/ncal.pas

@@ -4446,6 +4446,10 @@ implementation
               not tabstractprocdef(right.resultdef).is_addressonly then
              maybe_load_in_temp(right);
 
+           { the return value might be stored on the current stack by allocating a temp. }
+           if not(paramanager.ret_in_param(procdefinition.returndef,procdefinition)) then
+             inc(current_procinfo.estimatedtempsize,procdefinition.returndef.size);
+
            { Create destination (temp or assignment-variable reuse) for function result if it not yet set }
            maybe_create_funcret_node;
 

+ 2 - 0
compiler/nld.pas

@@ -1253,6 +1253,8 @@ implementation
         if do_variant then
           tarraydef(resultdef).elementdef:=search_system_type('TVARREC').typedef;
         expectloc:=LOC_CREFERENCE;
+
+        inc(current_procinfo.estimatedtempsize,(tarraydef(resultdef).highrange+1)*tarraydef(resultdef).elementdef.size);
       end;
 
 

+ 9 - 1
compiler/xtensa/cgcpu.pas

@@ -704,6 +704,7 @@ implementation
                       list.concat(tai_comment.Create(strpnew('  Max. outgoing parameter size: '+tostr(txtensaprocinfo(current_procinfo).maxpushedparasize))));
                       list.concat(tai_comment.Create(strpnew('  End of last temporary location: '+tostr(tg.lasttemp))));
                       list.concat(tai_comment.Create(strpnew('  Max. window rotation in bytes: '+tostr(txtensaprocinfo(current_procinfo).maxcall*4))));
+                      list.concat(tai_comment.Create(strpnew('  Required size after code generation: '+tostr(localsize))));
 
                       { should never happen as localsize is derived from
                         txtensaprocinfo(current_procinfo).stackframesize }
@@ -712,8 +713,15 @@ implementation
                       localsize:=txtensaprocinfo(current_procinfo).stackframesize;
                     end
                   else
-                    localsize:=align(localsize,current_settings.alignment.localalignmax);
+                    begin
+                      localsize:=align(localsize,current_settings.alignment.localalignmax);
+                      inc(localsize,4*4);
+                      if pi_do_call in current_procinfo.flags then
+                        inc(localsize,txtensaprocinfo(current_procinfo).maxcall*4);
+                    end;
 
+                  if localsize<0 then
+                    Internalerror(2020083001);
                   if localsize>32760 then
                     begin
                       list.concat(taicpu.op_reg_const(A_ENTRY,NR_STACK_POINTER_REG,32));

+ 38 - 2
compiler/xtensa/cpupara.pas

@@ -151,7 +151,7 @@ unit cpupara;
           recorddef :
             result:=(varspez = vs_const);
           arraydef:
-            result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
+            result:=((varspez = vs_const) and (tarraydef(def).highrange>=tarraydef(def).lowrange)) or
                              is_open_array(def) or
                              is_array_of_const(def) or
                              is_array_constructor(def);
@@ -299,7 +299,9 @@ unit cpupara;
       begin
         init_values(p,side,curintreg,cur_stack_offset);
 
-        result := create_paraloc_info_intern(p,side,p.paras,curintreg,cur_stack_offset,false);
+        result:=create_paraloc_info_intern(p,side,p.paras,curintreg,cur_stack_offset,false);
+        if result<cur_stack_offset then
+          Internalerror(2020083001);
 
         create_funcretloc_info(p,side);
       end;
@@ -327,6 +329,20 @@ unit cpupara;
          if po_explicitparaloc in p.procoptions then
            internalerror(200411141);
 {$endif extdebug}
+        loc.reset;
+        { currently only support C-style array of const }
+        if (p.proccalloption in cstylearrayofconst) and
+           is_array_of_const(paradef) then
+          begin
+            paraloc:=loc.add_location;
+            { hack: the paraloc must be valid, but is not actually used }
+            paraloc^.loc := LOC_REGISTER;
+            paraloc^.register := NR_A2;
+            paraloc^.size := OS_ADDR;
+            paraloc^.def:=voidpointertype;
+            result:=cur_stack_offset;
+            exit;
+          end;
 
          result:=0;
          nextintreg := curintreg;
@@ -469,12 +485,32 @@ unit cpupara;
                           end;
                        paralen := 0;
                     end;
+<<<<<<< HEAD
                   firstparaloc:=false;
                 end;
             end;
          curintreg:=nextintreg;
          cur_stack_offset:=stack_offset;
          result:=stack_offset;
+=======
+                 paralen := 0;
+              end;
+            firstparaloc:=false;
+          end;
+         result:=cur_stack_offset;
+      end;
+
+
+    function tcpuparamanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras:tparalist;
+      var curintreg: tsuperregister; var cur_stack_offset: aword; varargsparas: boolean):longint;
+      var
+        i : integer;
+      begin
+        result:=0;
+        for i:=0 to paras.count-1 do
+          result:=create_paraloc1_info_intern(p,side,tparavarsym(paras[i]).vardef,tparavarsym(paras[i]).paraloc[side],tparavarsym(paras[i]).varspez,
+            tparavarsym(paras[i]).varoptions,curintreg,cur_stack_offset,false);
+>>>>>>> 7962bf60e6... * squash stack frame size
       end;
 
 

+ 13 - 9
compiler/xtensa/cpupi.pas

@@ -76,7 +76,6 @@ unit cpupi;
             maxcall:=8;
 
             { we do not use a frame pointer for the windowed abi }
-            include(flags,pi_estimatestacksize);
             framepointer:=NR_STACK_POINTER_REG;
           end
         else
@@ -94,7 +93,7 @@ unit cpupi;
         localsize : aint;
         i : longint;
       begin
-        maxpushedparasize:=Align(maxpushedparasize,4);
+        maxpushedparasize:=Align(maxpushedparasize,target_info.alignment.localalignmax);
         tg.setfirsttemp(maxpushedparasize);
 
         if po_nostackframe in procdef.procoptions then
@@ -127,13 +126,16 @@ unit cpupi;
                     inc(localsize,256)
                   else
                     begin
-                      localsize:=align(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).vardef.alignment);
+                      localsize:=align(localsize,tparavarsym(procdef.parast.SymList[i]).paraloc[calleeside].alignment);
                       inc(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).getsize);
                     end;
                 end;
             inc(stackframesize,localsize);
-            stackframesize:=align(stackframesize,4);
 
+            stackframesize:=align(stackframesize,target_info.alignment.localalignmax);
+            inc(stackframesize,estimatedtempsize);
+
+            stackframesize:=align(stackframesize,4);
             if pi_needs_implicit_finally in flags then
               inc(stackframesize,40);
 
@@ -150,8 +152,6 @@ unit cpupi;
             if pi_do_call in current_procinfo.flags then
               inc(stackframesize,maxcall*4);
 
-            inc(stackframesize,estimatedtempsize);
-
             stackframesize:=Align(stackframesize,target_info.alignment.localalignmax);
           end;
       end;
@@ -159,13 +159,17 @@ unit cpupi;
 
     function txtensaprocinfo.calc_stackframe_size:longint;
       var
-         r : byte;
+         r, extra: byte;
          regs: tcpuregisterset;
       begin
-        maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
+//        maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
         if pi_estimatestacksize in flags then
           begin
-            if Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+4*4+maxcall*4>stackframesize then
+            if pi_do_call in current_procinfo.flags then
+              extra:=4*4+maxcall*4
+            else
+              extra:=0;
+            if Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+extra>stackframesize then
               InternalError(2020082801);
             result:=stackframesize
           end