Browse Source

* (de)allocation of registers for parameters is now performed properly
(and checked on the ppc)
- removed obsolete allocation of all parameter registers at the start
of a procedure (and deallocation at the end)

Jonas Maebe 22 years ago
parent
commit
55509b199b

+ 12 - 1
compiler/ncgcal.pas

@@ -132,6 +132,8 @@ implementation
          objectlibrary.getlabel(truelabel);
          objectlibrary.getlabel(truelabel);
          objectlibrary.getlabel(falselabel);
          objectlibrary.getlabel(falselabel);
          secondpass(left);
          secondpass(left);
+         { allocate paraloc }
+         paramanager.allocparaloc(exprasmlist,paraitem.paraloc);
          { handle varargs first, because defcoll is not valid }
          { handle varargs first, because defcoll is not valid }
          if (nf_varargs_para in flags) then
          if (nf_varargs_para in flags) then
            begin
            begin
@@ -918,6 +920,9 @@ implementation
             {$endif newra}
             {$endif newra}
            end;
            end;
 
 
+         { free the resources allocated for the parameters }
+         paramanager.freeparalocs(exprasmlist,tparaitem(procdefinition.para.first));
+
          { Need to remove the parameters from the stack? }
          { Need to remove the parameters from the stack? }
          if (po_clearstack in procdefinition.procoptions) then
          if (po_clearstack in procdefinition.procoptions) then
           begin
           begin
@@ -1407,7 +1412,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.89  2003-06-09 12:23:29  peter
+  Revision 1.90  2003-06-09 14:54:26  jonas
+    * (de)allocation of registers for parameters is now performed properly
+      (and checked on the ppc)
+    - removed obsolete allocation of all parameter registers at the start
+      of a procedure (and deallocation at the end)
+
+  Revision 1.89  2003/06/09 12:23:29  peter
     * init/final of procedure data splitted from genentrycode
     * init/final of procedure data splitted from genentrycode
     * use asmnode getposition to insert final at the correct position
     * use asmnode getposition to insert final at the correct position
       als for the implicit try...finally
       als for the implicit try...finally

+ 72 - 2
compiler/paramgr.pas

@@ -75,10 +75,34 @@ unit paramgr;
           {# frees a parameter location allocated with getintparaloc
           {# frees a parameter location allocated with getintparaloc
 
 
             @param(list Current assembler list)
             @param(list Current assembler list)
-            @param(nr Parameter numver of routine, starting from 1)
+            @param(nr Parameter number of routine, starting from 1)
           }
           }
           procedure freeintparaloc(list: taasmoutput; nr : longint); virtual;
           procedure freeintparaloc(list: taasmoutput; nr : longint); virtual;
 
 
+
+          {# allocate a parameter location created with create_param_loc_info
+
+            @param(list Current assembler list)
+            @param(loc Parameter location)
+          }
+          procedure allocparaloc(list: taasmoutput; const loc: tparalocation); virtual;
+
+          {# free a parameter location allocated with allocparaloc
+
+            @param(list Current assembler list)
+            @param(loc Parameter location)
+          }
+          procedure freeparaloc(list: taasmoutput; const loc: tparalocation); virtual;
+
+          {# free all parameters allocated with allocparaloc for a procedure
+
+            @param(list Current assembler list)
+            @param(paraitem First paraitem of the procedure)
+          }
+          procedure freeparalocs(list: taasmoutput; paraitem: tparaitem);
+
+
+
           {# This is used to populate the location information on all parameters
           {# This is used to populate the location information on all parameters
              for the routine. This is used for normal call resolution.
              for the routine. This is used for normal call resolution.
           }
           }
@@ -253,6 +277,46 @@ unit paramgr;
       end;
       end;
 
 
 
 
+    procedure tparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation);
+      begin
+        case loc.loc of
+          LOC_REGISTER, LOC_CREGISTER:
+            rg.getexplicitregisterint(list,loc.register.number);
+          LOC_FPUREGISTER, LOC_CFPUREGISTER:
+            rg.getexplicitregisterfpu(list,loc.register.enum);
+          LOC_REFERENCE,LOC_CREFERENCE:
+            { do nothing by default, most of the time it's the framepointer }
+          else
+            internalerror(200306091);
+        end;
+      end;
+
+
+    procedure tparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
+      begin
+        case loc.loc of
+          LOC_REGISTER, LOC_CREGISTER:
+            rg.ungetregisterint(list,loc.register);
+          LOC_FPUREGISTER, LOC_CFPUREGISTER:
+            rg.ungetregisterfpu(list,loc.register);
+          LOC_REFERENCE,LOC_CREFERENCE:
+            { do nothing by default, most of the time it's the framepointer }
+          else
+            internalerror(200306091);
+        end;
+      end;
+
+
+    procedure tparamanager.freeparalocs(list: taasmoutput; paraitem: tparaitem);
+      begin
+        while assigned(paraitem) do
+          begin
+            freeparaloc(list,paraitem.paraloc);
+            paraitem := tparaitem(paraitem.next);
+          end;
+      end;
+
+
     function tparamanager.getfuncretparaloc(p : tabstractprocdef) : tparalocation;
     function tparamanager.getfuncretparaloc(p : tabstractprocdef) : tparalocation;
       begin
       begin
          result.loc:=LOC_REFERENCE;
          result.loc:=LOC_REFERENCE;
@@ -395,7 +459,13 @@ end.
 
 
 {
 {
    $Log$
    $Log$
-   Revision 1.42  2003-06-08 10:54:41  jonas
+   Revision 1.43  2003-06-09 14:54:26  jonas
+     * (de)allocation of registers for parameters is now performed properly
+       (and checked on the ppc)
+     - removed obsolete allocation of all parameter registers at the start
+       of a procedure (and deallocation at the end)
+
+   Revision 1.42  2003/06/08 10:54:41  jonas
      - disabled changing of LOC_*REGISTER to LOC_C*REGISTER in setparalocs,
      - disabled changing of LOC_*REGISTER to LOC_C*REGISTER in setparalocs,
        this is not necessary anymore (doesn't do anything anymore actually,
        this is not necessary anymore (doesn't do anything anymore actually,
        except making sure the interface crc changes)
        except making sure the interface crc changes)

+ 7 - 34
compiler/powerpc/cgcpu.pas

@@ -993,13 +993,6 @@ const
              r.number:=NR_R11;
              r.number:=NR_R11;
              a_reg_alloc(list,r);
              a_reg_alloc(list,r);
           end;
           end;
-        { allocate registers containing reg parameters }
-        r.enum := R_INTREGISTER;
-        for regcounter2 := RS_R3 to RS_R10 do
-          begin
-            r.number:=regcounter2 shl 8;
-            a_reg_alloc(list,r);
-          end;
 
 
 
 
         usesfpr:=false;
         usesfpr:=false;
@@ -1227,13 +1220,6 @@ const
 
 
       begin
       begin
         localsize := 0;
         localsize := 0;
-        { release parameter registers }
-        r.enum := R_INTREGISTER;
-        for regcounter2 := RS_R3 to RS_R10 do
-          begin
-            r.number:=regcounter2 shl 8;
-            a_reg_dealloc(list,r);
-          end;
         { AltiVec context restore, not yet implemented !!! }
         { AltiVec context restore, not yet implemented !!! }
 
 
         usesfpr:=false;
         usesfpr:=false;
@@ -1545,16 +1531,6 @@ const
         a_reg_alloc(list,rsp);
         a_reg_alloc(list,rsp);
         a_reg_alloc(list,r);
         a_reg_alloc(list,r);
 
 
-        { allocate registers containing reg parameters }
-        r.enum := R_INTREGISTER;
-        for regcounter2 := RS_R3 to RS_R10 do
-          begin
-            r.number:=regcounter2 shl 8;
-            a_reg_alloc(list,r);
-          end;
-
-        {TODO: Allocate fp and altivec parameter registers also}
-
         { save return address in callers frame}
         { save return address in callers frame}
         r2.enum:=R_LR;
         r2.enum:=R_LR;
         list.concat(taicpu.op_reg_reg(A_MFSPR,r,r2));
         list.concat(taicpu.op_reg_reg(A_MFSPR,r,r2));
@@ -1628,15 +1604,6 @@ const
         r,r2,rsp:Tregister;
         r,r2,rsp:Tregister;
         regcounter2: Tsuperregister;
         regcounter2: Tsuperregister;
       begin
       begin
-        { release parameter registers }
-        r.enum := R_INTREGISTER;
-        for regcounter2 := RS_R3 to RS_R10 do
-          begin
-            r.number := regcounter2 shl 8;
-            a_reg_dealloc(list,r);
-          end;
-        {TODO: Release fp and altivec parameter registers also}
-
         r.enum:=R_INTREGISTER;
         r.enum:=R_INTREGISTER;
         r.number:=NR_R0;
         r.number:=NR_R0;
         rsp.enum:=R_INTREGISTER;
         rsp.enum:=R_INTREGISTER;
@@ -2565,7 +2532,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.106  2003-06-08 18:19:27  jonas
+  Revision 1.107  2003-06-09 14:54:26  jonas
+    * (de)allocation of registers for parameters is now performed properly
+      (and checked on the ppc)
+    - removed obsolete allocation of all parameter registers at the start
+      of a procedure (and deallocation at the end)
+
+  Revision 1.106  2003/06/08 18:19:27  jonas
     - removed duplicate identifier
     - removed duplicate identifier
 
 
   Revision 1.105  2003/06/07 18:57:04  jonas
   Revision 1.105  2003/06/07 18:57:04  jonas

+ 28 - 1
compiler/powerpc/cpupara.pas

@@ -38,6 +38,8 @@ unit cpupara;
           function push_addr_param(def : tdef;calloption : tproccalloption) : boolean;override;
           function push_addr_param(def : tdef;calloption : tproccalloption) : boolean;override;
           function getintparaloc(list: taasmoutput; nr : longint) : tparalocation;override;
           function getintparaloc(list: taasmoutput; nr : longint) : tparalocation;override;
           procedure freeintparaloc(list: taasmoutput; nr : longint); override;
           procedure freeintparaloc(list: taasmoutput; nr : longint); override;
+          procedure allocparaloc(list: taasmoutput; const loc: tparalocation);
+          procedure freeparaloc(list: taasmoutput; const loc: tparalocation);
           procedure create_param_loc_info(p : tabstractprocdef);override;
           procedure create_param_loc_info(p : tabstractprocdef);override;
           function getfuncretparaloc(p : tabstractprocdef) : tparalocation;override;
           function getfuncretparaloc(p : tabstractprocdef) : tparalocation;override;
        end;
        end;
@@ -90,6 +92,25 @@ unit cpupara;
            end;
            end;
       end;
       end;
 
 
+
+    procedure tppcparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation);
+      begin
+        if (loc.size in [OS_64,OS_S64]) and
+           (loc.loc in [LOC_REGISTER,LOC_CREGISTER])  then
+          rg.getexplicitregisterint(list,loc.registerhigh.number);
+        inherited allocparaloc(list,loc);
+      end;
+
+
+    procedure tppcparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
+      begin
+        if (loc.size in [OS_64,OS_S64]) and
+           (loc.loc in [LOC_REGISTER,LOC_CREGISTER])  then
+          rg.ungetregisterint(list,loc.registerhigh);
+        inherited allocparaloc(list,loc);
+      end;
+
+
     function getparaloc(p : tdef) : tcgloc;
     function getparaloc(p : tdef) : tcgloc;
 
 
       begin
       begin
@@ -364,7 +385,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.36  2003-06-08 10:52:01  jonas
+  Revision 1.37  2003-06-09 14:54:26  jonas
+    * (de)allocation of registers for parameters is now performed properly
+      (and checked on the ppc)
+    - removed obsolete allocation of all parameter registers at the start
+      of a procedure (and deallocation at the end)
+
+  Revision 1.36  2003/06/08 10:52:01  jonas
     * zero paraloc tregisters, so that the alignment bytes are 0 (otherwise
     * zero paraloc tregisters, so that the alignment bytes are 0 (otherwise
       the crc of the ppu files can change between interface and
       the crc of the ppu files can change between interface and
       implementation)
       implementation)

+ 45 - 7
compiler/powerpc/rgcpu.pas

@@ -37,6 +37,8 @@ unit rgcpu;
        trgcpu = class(trgobj)
        trgcpu = class(trgobj)
          function getexplicitregisterint(list: taasmoutput; reg: Tnewregister): tregister; override;
          function getexplicitregisterint(list: taasmoutput; reg: Tnewregister): tregister; override;
          procedure ungetregisterint(list: taasmoutput; reg: tregister); override;
          procedure ungetregisterint(list: taasmoutput; reg: tregister); override;
+         function getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;override;
+         procedure ungetregisterfpu(list: taasmoutput; r : tregister);override;
          procedure saveusedintregisters(list:Taasmoutput;
          procedure saveusedintregisters(list:Taasmoutput;
                                          var saved:Tpushedsavedint;
                                          var saved:Tpushedsavedint;
                                          const s:Tsupregset);override;
                                          const s:Tsupregset);override;
@@ -46,6 +48,7 @@ unit rgcpu;
          procedure cleartempgen; override;
          procedure cleartempgen; override;
         private
         private
          usedpararegs: Tsupregset;
          usedpararegs: Tsupregset;
+         usedparafpuregs: tregisterset;
        end;
        end;
 
 
   implementation
   implementation
@@ -55,8 +58,6 @@ unit rgcpu;
 
 
     function trgcpu.getexplicitregisterint(list: taasmoutput; reg: Tnewregister): tregister;
     function trgcpu.getexplicitregisterint(list: taasmoutput; reg: Tnewregister): tregister;
 
 
-    var r:Tregister;
-
       begin
       begin
         if ((reg shr 8) in [RS_R0,RS_R2..RS_R12]) and
         if ((reg shr 8) in [RS_R0,RS_R2..RS_R12]) and
            not((reg shr 8) in is_reg_var_int) then
            not((reg shr 8) in is_reg_var_int) then
@@ -64,10 +65,9 @@ unit rgcpu;
             if (reg shr 8) in usedpararegs then
             if (reg shr 8) in usedpararegs then
               internalerror(2003060701);
               internalerror(2003060701);
             include(usedpararegs,reg shr 8);
             include(usedpararegs,reg shr 8);
-            r.enum:=R_INTREGISTER;
-            r.number:=reg;
-            cg.a_reg_alloc(list,r);
-            result := r;
+            result.enum:=R_INTREGISTER;
+            result.number:=reg;
+            cg.a_reg_alloc(list,result);
           end
           end
         else result := inherited getexplicitregisterint(list,reg);
         else result := inherited getexplicitregisterint(list,reg);
       end;
       end;
@@ -89,6 +89,37 @@ unit rgcpu;
       end;
       end;
 
 
 
 
+    function trgcpu.getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;
+      begin
+        if (r in [R_F1..R_F13]) and
+           not is_reg_var_other[r] then
+          begin
+            if r in usedparafpuregs then
+              internalerror(2003060902);
+            include(usedparafpuregs,r);
+            result.enum := r;
+            cg.a_reg_alloc(list,result);
+          end
+        else
+          result := inherited getexplicitregisterfpu(list,r);
+      end;
+
+
+    procedure trgcpu.ungetregisterfpu(list: taasmoutput; r : tregister);
+      begin
+        if (r.enum in [R_F1..R_F13]) and
+           not is_reg_var_other[r.enum] then
+          begin
+            if not(r.enum in usedparafpuregs) then
+              internalerror(2003060903);
+            exclude(usedparafpuregs,r.enum);
+            cg.a_reg_dealloc(list,r);
+          end
+        else
+          inherited ungetregisterfpu(list,r);
+      end;
+
+
     procedure trgcpu.saveusedintregisters(list:Taasmoutput;
     procedure trgcpu.saveusedintregisters(list:Taasmoutput;
                                          var saved:Tpushedsavedint;
                                          var saved:Tpushedsavedint;
                                          const s:Tsupregset);
                                          const s:Tsupregset);
@@ -116,6 +147,7 @@ unit rgcpu;
       begin
       begin
         inherited cleartempgen;
         inherited cleartempgen;
         usedpararegs := [];
         usedpararegs := [];
+        usedparafpuregs := [];
       end;
       end;
 
 
 initialization
 initialization
@@ -124,7 +156,13 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.8  2003-06-07 18:57:04  jonas
+  Revision 1.9  2003-06-09 14:54:26  jonas
+    * (de)allocation of registers for parameters is now performed properly
+      (and checked on the ppc)
+    - removed obsolete allocation of all parameter registers at the start
+      of a procedure (and deallocation at the end)
+
+  Revision 1.8  2003/06/07 18:57:04  jonas
     + added freeintparaloc
     + added freeintparaloc
     * ppc get/freeintparaloc now check whether the parameter regs are
     * ppc get/freeintparaloc now check whether the parameter regs are
       properly allocated/deallocated (and get an extra list para)
       properly allocated/deallocated (and get an extra list para)

+ 8 - 2
compiler/rgobj.pas

@@ -280,7 +280,7 @@ unit rgobj;
 
 
              @param(r specific register to allocate)
              @param(r specific register to allocate)
           }
           }
-          function getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;
+          function getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;virtual;
 
 
           {# Deallocate any kind of register }
           {# Deallocate any kind of register }
           procedure ungetregister(list: taasmoutput; r : tregister); virtual;
           procedure ungetregister(list: taasmoutput; r : tregister); virtual;
@@ -2463,7 +2463,13 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.50  2003-06-03 21:11:09  peter
+  Revision 1.51  2003-06-09 14:54:26  jonas
+    * (de)allocation of registers for parameters is now performed properly
+      (and checked on the ppc)
+    - removed obsolete allocation of all parameter registers at the start
+      of a procedure (and deallocation at the end)
+
+  Revision 1.50  2003/06/03 21:11:09  peter
     * cg.a_load_* get a from and to size specifier
     * cg.a_load_* get a from and to size specifier
     * makeregsize only accepts newregister
     * makeregsize only accepts newregister
     * i386 uses generic tcgnotnode,tcgunaryminus
     * i386 uses generic tcgnotnode,tcgunaryminus