Browse Source

* fixed internalerrors on non-use_fixed_stack platforms after r16050:
stack parameters can also be split over multiple locations

git-svn-id: trunk@16052 -

Jonas Maebe 15 years ago
parent
commit
6094cb79dc
2 changed files with 30 additions and 23 deletions
  1. 6 6
      compiler/ncgcal.pas
  2. 24 17
      compiler/paramgr.pas

+ 6 - 6
compiler/ncgcal.pas

@@ -485,7 +485,7 @@ implementation
          href : treference;
          href : treference;
          calleralignment,
          calleralignment,
          tmpalignment: longint;
          tmpalignment: longint;
-         skipmemloc: boolean;
+         skipiffinalloc: boolean;
        begin
        begin
          { copy all resources to the allocated registers }
          { copy all resources to the allocated registers }
          ppn:=tcgcallparanode(left);
          ppn:=tcgcallparanode(left);
@@ -505,10 +505,9 @@ implementation
                     (calleralignment=0) then
                     (calleralignment=0) then
                    internalerror(2009020701);
                    internalerror(2009020701);
                  callerparaloc:=ppn.parasym.paraloc[callerside].location;
                  callerparaloc:=ppn.parasym.paraloc[callerside].location;
-                 skipmemloc:=
-                   (not paramanager.use_fixed_stack or
-                    not(ppn.followed_by_stack_tainting_call_cached)) and
-                   paramanager.is_simple_stack_paraloc(callerparaloc);
+                 skipiffinalloc:=
+                   not paramanager.use_fixed_stack or
+                   not(ppn.followed_by_stack_tainting_call_cached);
                  while assigned(callerparaloc) do
                  while assigned(callerparaloc) do
                    begin
                    begin
                      { Every paraloc must have a matching tmpparaloc }
                      { Every paraloc must have a matching tmpparaloc }
@@ -545,7 +544,8 @@ implementation
                          end;
                          end;
                        LOC_REFERENCE:
                        LOC_REFERENCE:
                          begin
                          begin
-                           if not skipmemloc then
+                           if skipiffinalloc and
+                              paramanager.is_stack_paraloc(callerparaloc) then
                              begin
                              begin
                                { Can't have a data copied to the stack, every location
                                { Can't have a data copied to the stack, every location
                                  must contain a valid size field }
                                  must contain a valid size field }

+ 24 - 17
compiler/paramgr.pas

@@ -124,8 +124,9 @@ unit paramgr;
           }
           }
           function  create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;virtual;abstract;
           function  create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;virtual;abstract;
 
 
-          function is_simple_stack_paraloc(paraloc: pcgparalocation): boolean;
+          function is_stack_paraloc(paraloc: pcgparalocation): boolean;
           procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);virtual;
           procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);virtual;
+          procedure duplicatecgparaloc(const orgparaloc: pcgparalocation; intonewparaloc: pcgparalocation);
           procedure duplicateparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);
           procedure duplicateparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);
 
 
           function parseparaloc(parasym : tparavarsym;const s : string) : boolean;virtual;
           function parseparaloc(parasym : tparavarsym;const s : string) : boolean;virtual;
@@ -327,13 +328,12 @@ implementation
       end;
       end;
 
 
 
 
-    function tparamanager.is_simple_stack_paraloc(paraloc: pcgparalocation): boolean;
+    function tparamanager.is_stack_paraloc(paraloc: pcgparalocation): boolean;
       begin
       begin
         result:=
         result:=
           assigned(paraloc) and
           assigned(paraloc) and
           (paraloc^.loc=LOC_REFERENCE) and
           (paraloc^.loc=LOC_REFERENCE) and
-          (paraloc^.reference.index=NR_STACK_POINTER_REG) and
-          not assigned(paraloc^.next);
+          (paraloc^.reference.index=NR_STACK_POINTER_REG);
       end;
       end;
 
 
 
 
@@ -345,13 +345,6 @@ implementation
         newparaloc : pcgparalocation;
         newparaloc : pcgparalocation;
       begin
       begin
         paraloc:=parasym.paraloc[callerside].location;
         paraloc:=parasym.paraloc[callerside].location;
-        if can_use_final_stack_loc and
-           is_simple_stack_paraloc(paraloc) then
-          begin
-            duplicateparaloc(list,calloption,parasym,cgpara);
-            exit;
-          end;
-
         cgpara.reset;
         cgpara.reset;
         cgpara.size:=parasym.paraloc[callerside].size;
         cgpara.size:=parasym.paraloc[callerside].size;
         cgpara.intsize:=parasym.paraloc[callerside].intsize;
         cgpara.intsize:=parasym.paraloc[callerside].intsize;
@@ -372,7 +365,9 @@ implementation
               i386 isn't affected anyways because it uses the stack to push parameters
               i386 isn't affected anyways because it uses the stack to push parameters
               on arm it reduces executable size of the compiler by 2.1 per cent (FK) }
               on arm it reduces executable size of the compiler by 2.1 per cent (FK) }
             { Does it fit a register? }
             { Does it fit a register? }
-            if (len<=sizeof(pint)) and
+            if (not can_use_final_stack_loc or
+                not is_stack_paraloc(paraloc)) and
+               (len<=sizeof(pint)) and
                (paraloc^.size in [OS_8,OS_16,OS_32,OS_64,OS_128,OS_S8,OS_S16,OS_S32,OS_S64,OS_S128]) then
                (paraloc^.size in [OS_8,OS_16,OS_32,OS_64,OS_128,OS_S8,OS_S16,OS_S32,OS_S64,OS_S128]) then
               newparaloc^.loc:=LOC_REGISTER
               newparaloc^.loc:=LOC_REGISTER
             else
             else
@@ -386,9 +381,15 @@ implementation
                 newparaloc^.register:=cg.getmmregister(list,paraloc^.size);
                 newparaloc^.register:=cg.getmmregister(list,paraloc^.size);
               LOC_REFERENCE :
               LOC_REFERENCE :
                 begin
                 begin
-                  tg.gettemp(list,len,cgpara.alignment,tt_persistent,href);
-                  newparaloc^.reference.index:=href.base;
-                  newparaloc^.reference.offset:=href.offset;
+                  if can_use_final_stack_loc and
+                     is_stack_paraloc(paraloc) then
+                    duplicatecgparaloc(paraloc,newparaloc)
+                  else
+                    begin
+                      tg.gettemp(list,len,cgpara.alignment,tt_persistent,href);
+                      newparaloc^.reference.index:=href.base;
+                      newparaloc^.reference.offset:=href.offset;
+                    end;
                 end;
                 end;
             end;
             end;
             paraloc:=paraloc^.next;
             paraloc:=paraloc^.next;
@@ -396,6 +397,13 @@ implementation
       end;
       end;
 
 
 
 
+    procedure tparamanager.duplicatecgparaloc(const orgparaloc: pcgparalocation; intonewparaloc: pcgparalocation);
+      begin
+        move(orgparaloc^,intonewparaloc^,sizeof(intonewparaloc^));
+        intonewparaloc^.next:=nil;
+      end;
+
+
     procedure tparamanager.duplicateparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);
     procedure tparamanager.duplicateparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);
       var
       var
         paraloc,
         paraloc,
@@ -412,8 +420,7 @@ implementation
         while assigned(paraloc) do
         while assigned(paraloc) do
           begin
           begin
             newparaloc:=cgpara.add_location;
             newparaloc:=cgpara.add_location;
-            move(paraloc^,newparaloc^,sizeof(newparaloc^));
-            newparaloc^.next:=nil;
+            duplicatecgparaloc(paraloc,newparaloc);
             paraloc:=paraloc^.next;
             paraloc:=paraloc^.next;
           end;
           end;
       end;
       end;