Browse Source

* Xtensa: stack size calculation for the call0 abi fixed

git-svn-id: trunk@46833 -
florian 5 years ago
parent
commit
8e74a04dc5
2 changed files with 38 additions and 6 deletions
  1. 27 6
      compiler/xtensa/cgcpu.pas
  2. 11 0
      compiler/xtensa/cpupara.pas

+ 27 - 6
compiler/xtensa/cgcpu.pas

@@ -660,10 +660,27 @@ implementation
                            inc(registerarea,4);
                      end;
 
-                  inc(localsize,registerarea);
-                  if LocalSize<>0 then
+                  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('  Size of register area: '+tostr(registerarea))));
+                      list.concat(tai_comment.Create(strpnew('  Required size after code generation: '+tostr(localsize))));
+
+                      if localsize>txtensaprocinfo(current_procinfo).stackframesize then
+                        internalerror(2020091001);
+                      localsize:=txtensaprocinfo(current_procinfo).stackframesize;
+                    end
+                  else
                     begin
+                      inc(localsize,registerarea);
                       localsize:=align(localsize,current_settings.alignment.localalignmax);
+                    end;
+
+                  if LocalSize<>0 then
+                    begin
                       a_reg_alloc(list,NR_STACK_POINTER_REG);
                       list.concat(taicpu.op_reg_reg_const(A_ADDI,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-localsize));
                     end;
@@ -785,11 +802,16 @@ implementation
                          if r in regs then
                            inc(registerarea,4);
                      end;
-                  inc(localsize,registerarea);
 
-                  if LocalSize<>0 then
+                  { do we use then estimated stack size? }
+                  if not(stack_parameters and (pi_estimatestacksize in current_procinfo.flags)) then
                     begin
+                      inc(localsize,registerarea);
                       localsize:=align(localsize,current_settings.alignment.localalignmax);
+                    end;
+
+                  if LocalSize<>0 then
+                    begin
                       // Determine reference mode required to access stack
                       reference_reset(ref,4,[]);
                       ref.base:=NR_STACK_POINTER_REG;
@@ -798,8 +820,7 @@ implementation
                         begin
                           if ref.offset<=1024+32512 then
                             begin
-                              // allocation done in proc_entry
-                              //list.concat(taicpu.op_reg_reg_const(A_ADDMI,NR_A8,NR_STACK_POINTER_REG,ref.offset and $fffffc00));
+                              list.concat(taicpu.op_reg_reg_const(A_ADDMI,NR_A8,NR_STACK_POINTER_REG,ref.offset and $fffffc00));
                               ref.offset:=ref.offset and $3ff;
                               ref.base:=NR_A8;
                             end

+ 11 - 0
compiler/xtensa/cpupara.pas

@@ -41,6 +41,7 @@ unit cpupara;
          function create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;override;
          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
          function ret_in_param(def: tdef; pd: tabstractprocdef): boolean;override;
+         function param_use_paraloc(const cgpara: tcgpara): boolean;override;
        private
          { the max. register depends on the used call instruction }
          maxintreg : TSuperRegister;
@@ -105,6 +106,16 @@ unit cpupara;
       end;
 
 
+    function tcpuparamanager.param_use_paraloc(const cgpara: tcgpara): boolean;
+      begin
+        { we always set up a stack frame -> we can always access the parameters
+          this way }
+        result:=
+          (cgpara.location^.loc=LOC_REFERENCE) and
+          not assigned(cgpara.location^.next);
+      end;
+
+
     function tcpuparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
       begin
         result:=false;