Bläddra i källkod

+ 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 år sedan
förälder
incheckning
075abd6220

+ 6 - 0
compiler/arm/cgcpu.pas

@@ -3375,6 +3375,12 @@ unit cgcpu;
          imm1, imm2: DWord;
          imm1, imm2: DWord;
       begin
       begin
         LocalSize:=align(LocalSize,4);
         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 }
         { call instruction does not put anything on the stack }
         stackmisalignment:=0;
         stackmisalignment:=0;
         if not(nostackframe) then
         if not(nostackframe) then

+ 45 - 2
compiler/arm/cpupi.pas

@@ -33,6 +33,11 @@ unit cpupi;
 
 
     type
     type
        tarmprocinfo = class(tcgprocinfo)
        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;
           floatregstart : aint;
           // procedure handle_body_start;override;
           // procedure handle_body_start;override;
           // procedure after_pass1;override;
           // procedure after_pass1;override;
@@ -48,11 +53,15 @@ unit cpupi;
        globals,systems,
        globals,systems,
        cpubase,
        cpubase,
        tgobj,
        tgobj,
-       symconst,paramgr,
+       symconst,symtype,symsym,paramgr,
        cgbase,cgutils,
        cgbase,cgutils,
-       cgobj;
+       cgobj,
+       defutil;
 
 
     procedure tarmprocinfo.set_first_temp_offset;
     procedure tarmprocinfo.set_first_temp_offset;
+      var
+        localsize : aint;
+        i : longint;
       begin
       begin
         { We allocate enough space to save all registers because we can't determine
         { We allocate enough space to save all registers because we can't determine
           the necessary space because the used registers aren't known before
           the necessary space because the used registers aren't known before
@@ -84,6 +93,40 @@ unit cpupi;
           end
           end
         else
         else
           tg.setfirsttemp(maxpushedparasize);
           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;
       end;
 
 
 
 

+ 1 - 0
compiler/nbas.pas

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

+ 2 - 9
compiler/ncgutil.pas

@@ -392,15 +392,8 @@ implementation
 *****************************************************************************}
 *****************************************************************************}
 
 
     procedure get_exception_temps(list:TAsmList;var t:texceptiontemps);
     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,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,jmp_buf_size,jmp_buf_align,tt_persistent,t.jmpbuf);
         tg.GetTemp(list,sizeof(pint),sizeof(pint),tt_persistent,t.reasonbuf);
         tg.GetTemp(list,sizeof(pint),sizeof(pint),tt_persistent,t.reasonbuf);

+ 2 - 0
compiler/ncnv.pas

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

+ 3 - 1
compiler/nflw.pas

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

+ 4 - 0
compiler/procinfo.pas

@@ -125,6 +125,10 @@ unit procinfo;
           { max. of space need for parameters }
           { max. of space need for parameters }
           maxpushedparasize : aint;
           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
           { is this a constructor that calls another constructor on itself
             (either inherited, or another constructor of the same class)?
             (either inherited, or another constructor of the same class)?
             Requires different entry code for some targets. }
             Requires different entry code for some targets. }

+ 15 - 0
compiler/symtable.pas

@@ -220,6 +220,7 @@ interface
     procedure hidesym(sym:TSymEntry);
     procedure hidesym(sym:TSymEntry);
     procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry);
     procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry);
     function handle_generic_dummysym(sym:TSymEntry;var symoptions:tsymoptions):boolean;
     function handle_generic_dummysym(sym:TSymEntry;var symoptions:tsymoptions):boolean;
+    function get_jumpbuf_size : longint;
 
 
 {*** Search ***}
 {*** Search ***}
     procedure addsymref(sym:tsym);
     procedure addsymref(sym:tsym);
@@ -2046,6 +2047,20 @@ implementation
           end;
           end;
       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
                                   Search
 *****************************************************************************}
 *****************************************************************************}