Ver código fonte

* Xtensa: various stack handling fixes

git-svn-id: trunk@46732 -
florian 5 anos atrás
pai
commit
867ed59459
2 arquivos alterados com 41 adições e 21 exclusões
  1. 11 12
      compiler/xtensa/cgcpu.pas
  2. 30 9
      compiler/xtensa/cpupi.pas

+ 11 - 12
compiler/xtensa/cgcpu.pas

@@ -699,21 +699,20 @@ implementation
                 begin
                   if stack_parameters and (pi_estimatestacksize in current_procinfo.flags) then
                     begin
+                      list.concat(tai_comment.Create(strpnew('Stackframe size was estimated before code generation due to stack parameters')));
+                      list.concat(tai_comment.Create(strpnew('  Calculated stackframe size: '+tostr(txtensaprocinfo(current_procinfo).stackframesize))));
+                      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))));
+
+                      { should never happen as localsize is derived from
+                        txtensaprocinfo(current_procinfo).stackframesize }
                       if localsize>txtensaprocinfo(current_procinfo).stackframesize then
-                        internalerror(2020031402)
-                      else
-                        localsize:=txtensaprocinfo(current_procinfo).stackframesize-registerarea;
+                        internalerror(2020031402);
+                      localsize:=txtensaprocinfo(current_procinfo).stackframesize;
                     end
                   else
-                    begin
-                      { default spill area }
-                      inc(localsize,4*4);
-                      { additional spill area? }
-                      if pi_do_call in current_procinfo.flags then
-                        inc(localsize,txtensaprocinfo(current_procinfo).maxcall*4);
-
-                      localsize:=align(localsize,current_settings.alignment.localalignmax);
-                    end;
+                    localsize:=align(localsize,current_settings.alignment.localalignmax);
 
                   if localsize>32760 then
                     begin

+ 30 - 9
compiler/xtensa/cpupi.pas

@@ -56,6 +56,7 @@ unit cpupi;
 
     uses
        globals,systems,
+       verbose,
        tgobj,
        symconst,symtype,symsym,symcpu,paramgr,
        cgutils,
@@ -102,25 +103,36 @@ unit cpupi;
         { estimate stack frame size }
         if pi_estimatestacksize in flags then
           begin
-            stackframesize:=maxpushedparasize;
+            stackframesize:=align(maxpushedparasize,target_info.alignment.localalignmax);
             localsize:=0;
             for i:=0 to procdef.localst.SymList.Count-1 do
               if tsym(procdef.localst.SymList[i]).typ=localvarsym then
-                inc(localsize,tabstractnormalvarsym(procdef.localst.SymList[i]).getsize);
+                begin
+                  localsize:=align(localsize,tabstractnormalvarsym(procdef.localst.SymList[i]).vardef.alignment);
+                  inc(localsize,tabstractnormalvarsym(procdef.localst.SymList[i]).getsize);
+                end;
             inc(stackframesize,localsize);
+            stackframesize:=align(stackframesize,target_info.alignment.localalignmax);
 
             localsize:=0;
             for i:=0 to procdef.parast.SymList.Count-1 do
               if tsym(procdef.parast.SymList[i]).typ=paravarsym then
                 begin
                   if tabstractnormalvarsym(procdef.parast.SymList[i]).varspez in [vs_var,vs_out,vs_constref] then
-                    inc(localsize,4)
+                    begin
+                      localsize:=align(localsize,4);
+                      inc(localsize,4)
+                    end
                   else if is_open_string(tabstractnormalvarsym(procdef.parast.SymList[i]).vardef) then
                     inc(localsize,256)
                   else
-                    inc(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).getsize);
+                    begin
+                      localsize:=align(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).vardef.alignment);
+                      inc(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).getsize);
+                    end;
                 end;
             inc(stackframesize,localsize);
+            stackframesize:=align(stackframesize,4);
 
             if pi_needs_implicit_finally in flags then
               inc(stackframesize,40);
@@ -131,6 +143,13 @@ unit cpupi;
             if procdef.proctypeoption in [potype_constructor] then
               inc(stackframesize,40*2);
 
+            { default spill area }
+            inc(stackframesize,4*4);
+
+            { additional spill area? }
+            if pi_do_call in current_procinfo.flags then
+              inc(stackframesize,maxcall*4);
+
             inc(stackframesize,estimatedtempsize);
 
             stackframesize:=Align(stackframesize,target_info.alignment.localalignmax);
@@ -143,13 +162,15 @@ unit cpupi;
          r : byte;
          regs: tcpuregisterset;
       begin
+        maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
         if pi_estimatestacksize in flags then
-          result:=stackframesize
-        else
           begin
-            maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
-            result:=Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+maxpushedparasize;
-          end;
+            if Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+4*4+maxcall*4>stackframesize then
+              InternalError(2020082801);
+            result:=stackframesize
+          end
+        else
+          result:=Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+maxpushedparasize;
       end;