Jelajahi Sumber

+ support of stackframesize for arm thumb
+ estimatedtempsize to get a good estimatation for architectures which require to know the stack size before

git-svn-id: trunk@24188 -

florian 12 tahun lalu
induk
melakukan
075abd6220

+ 6 - 0
compiler/arm/cgcpu.pas

@@ -3375,6 +3375,12 @@ unit cgcpu;
          imm1, imm2: DWord;
       begin
         LocalSize:=align(LocalSize,4);
+        if localsize>tarmprocinfo(current_procinfo).stackframesize then
+          begin
+            writeln(localsize);
+            writeln(tarmprocinfo(current_procinfo).stackframesize);
+            internalerror(2013040101);
+          end;
         { call instruction does not put anything on the stack }
         stackmisalignment:=0;
         if not(nostackframe) then

+ 45 - 2
compiler/arm/cpupi.pas

@@ -33,6 +33,11 @@ unit cpupi;
 
     type
        tarmprocinfo = class(tcgprocinfo)
+          { for arm thumb, we need to know the stackframe size before
+            starting procedure compilation, so this contains the stack frame size, the compiler
+            should assume
+            if this size is too little the procedure must be compiled again with a larger value }
+          stackframesize,
           floatregstart : aint;
           // procedure handle_body_start;override;
           // procedure after_pass1;override;
@@ -48,11 +53,15 @@ unit cpupi;
        globals,systems,
        cpubase,
        tgobj,
-       symconst,paramgr,
+       symconst,symtype,symsym,paramgr,
        cgbase,cgutils,
-       cgobj;
+       cgobj,
+       defutil;
 
     procedure tarmprocinfo.set_first_temp_offset;
+      var
+        localsize : aint;
+        i : longint;
       begin
         { We allocate enough space to save all registers because we can't determine
           the necessary space because the used registers aren't known before
@@ -84,6 +93,40 @@ unit cpupi;
           end
         else
           tg.setfirsttemp(maxpushedparasize);
+
+        { estimate stack frame size }
+        if current_settings.cputype in cpu_thumb then
+          begin
+            stackframesize:=maxpushedparasize+32;
+            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);
+            inc(stackframesize,localsize);
+
+            localsize:=0;
+            for i:=0 to procdef.parast.SymList.Count-1 do
+              if tsym(procdef.parast.SymList[i]).typ=paravarsym then
+                if is_open_string(tabstractnormalvarsym(procdef.parast.SymList[i]).vardef) then
+                  inc(localsize,256)
+                else
+                  inc(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).getsize);
+
+            inc(stackframesize,localsize);
+
+            if pi_needs_implicit_finally in flags then
+              inc(stackframesize,40);
+
+            if pi_uses_exceptions in flags then
+              inc(stackframesize,40);
+
+            if procdef.proctypeoption in [potype_constructor] then
+              inc(stackframesize,40*2);
+
+            inc(stackframesize,estimatedtempsize);
+
+            stackframesize:=Align(stackframesize,8);
+          end;
       end;
 
 

+ 1 - 0
compiler/nbas.pas

@@ -918,6 +918,7 @@ implementation
           firstpass(tempinfo^.withnode);
         if assigned(tempinfo^.tempinitcode) then
           firstpass(tempinfo^.tempinitcode);
+        inc(current_procinfo.estimatedtempsize,size);;
       end;
 
 

+ 2 - 9
compiler/ncgutil.pas

@@ -392,15 +392,8 @@ implementation
 *****************************************************************************}
 
     procedure get_exception_temps(list:TAsmList;var t:texceptiontemps);
-      var
-        srsym : ttypesym;
-      begin
-        if jmp_buf_size=-1 then
-          begin
-            srsym:=search_system_type('JMP_BUF');
-            jmp_buf_size:=srsym.typedef.size;
-            jmp_buf_align:=srsym.typedef.alignment;
-          end;
+     begin
+        get_jumpbuf_size;
         tg.GetTemp(list,EXCEPT_BUF_SIZE,sizeof(pint),tt_persistent,t.envbuf);
         tg.GetTemp(list,jmp_buf_size,jmp_buf_align,tt_persistent,t.jmpbuf);
         tg.GetTemp(list,sizeof(pint),sizeof(pint),tt_persistent,t.reasonbuf);

+ 2 - 0
compiler/ncnv.pas

@@ -2856,6 +2856,8 @@ implementation
 
       begin
          first_char_to_string:=nil;
+         if tstringdef(resultdef).stringtype=st_shortstring then
+           inc(current_procinfo.estimatedtempsize,256);
          expectloc:=LOC_REFERENCE;
       end;
 

+ 3 - 1
compiler/nflw.pas

@@ -1995,6 +1995,7 @@ implementation
          { else block }
          if assigned(t1) then
            firstpass(t1);
+         inc(current_procinfo.estimatedtempsize,get_jumpbuf_size*2);
       end;
 
 
@@ -2051,6 +2052,8 @@ implementation
 
          if assigned(t1) then
            firstpass(t1);
+
+         inc(current_procinfo.estimatedtempsize,get_jumpbuf_size);
       end;
 
 
@@ -2067,7 +2070,6 @@ implementation
          end;
      end;
 
-
 {*****************************************************************************
                                 TONNODE
 *****************************************************************************}

+ 4 - 0
compiler/procinfo.pas

@@ -125,6 +125,10 @@ unit procinfo;
           { max. of space need for parameters }
           maxpushedparasize : aint;
 
+          { some architectures need to know a stack size before the first compilation pass
+            estimatedtempsize contains an estimated value how big temps will get }
+          estimatedtempsize : aint;
+
           { is this a constructor that calls another constructor on itself
             (either inherited, or another constructor of the same class)?
             Requires different entry code for some targets. }

+ 15 - 0
compiler/symtable.pas

@@ -220,6 +220,7 @@ interface
     procedure hidesym(sym:TSymEntry);
     procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry);
     function handle_generic_dummysym(sym:TSymEntry;var symoptions:tsymoptions):boolean;
+    function get_jumpbuf_size : longint;
 
 {*** Search ***}
     procedure addsymref(sym:tsym);
@@ -2046,6 +2047,20 @@ implementation
           end;
       end;
 
+
+    function get_jumpbuf_size : longint;
+      var
+        srsym : ttypesym;
+      begin
+        if jmp_buf_size=-1 then
+          begin
+            srsym:=search_system_type('JMP_BUF');
+            jmp_buf_size:=srsym.typedef.size;
+            jmp_buf_align:=srsym.typedef.alignment;
+          end;
+        result:=jmp_buf_size;
+      end;
+
 {*****************************************************************************
                                   Search
 *****************************************************************************}