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
6 changed files with 172 additions and 47 deletions
  1. 12 1
      compiler/ncgcal.pas
  2. 72 2
      compiler/paramgr.pas
  3. 7 34
      compiler/powerpc/cgcpu.pas
  4. 28 1
      compiler/powerpc/cpupara.pas
  5. 45 7
      compiler/powerpc/rgcpu.pas
  6. 8 2
      compiler/rgobj.pas

+ 12 - 1
compiler/ncgcal.pas

@@ -132,6 +132,8 @@ implementation
          objectlibrary.getlabel(truelabel);
          objectlibrary.getlabel(falselabel);
          secondpass(left);
+         { allocate paraloc }
+         paramanager.allocparaloc(exprasmlist,paraitem.paraloc);
          { handle varargs first, because defcoll is not valid }
          if (nf_varargs_para in flags) then
            begin
@@ -918,6 +920,9 @@ implementation
             {$endif newra}
            end;
 
+         { free the resources allocated for the parameters }
+         paramanager.freeparalocs(exprasmlist,tparaitem(procdefinition.para.first));
+
          { Need to remove the parameters from the stack? }
          if (po_clearstack in procdefinition.procoptions) then
           begin
@@ -1407,7 +1412,13 @@ begin
 end.
 {
   $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
     * use asmnode getposition to insert final at the correct position
       als for the implicit try...finally

+ 72 - 2
compiler/paramgr.pas

@@ -75,10 +75,34 @@ unit paramgr;
           {# frees a parameter location allocated with getintparaloc
 
             @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;
 
+
+          {# 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
              for the routine. This is used for normal call resolution.
           }
@@ -253,6 +277,46 @@ unit paramgr;
       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;
       begin
          result.loc:=LOC_REFERENCE;
@@ -395,7 +459,13 @@ end.
 
 {
    $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,
        this is not necessary anymore (doesn't do anything anymore actually,
        except making sure the interface crc changes)

+ 7 - 34
compiler/powerpc/cgcpu.pas

@@ -993,13 +993,6 @@ const
              r.number:=NR_R11;
              a_reg_alloc(list,r);
           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;
@@ -1227,13 +1220,6 @@ const
 
       begin
         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 !!! }
 
         usesfpr:=false;
@@ -1545,16 +1531,6 @@ const
         a_reg_alloc(list,rsp);
         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}
         r2.enum:=R_LR;
         list.concat(taicpu.op_reg_reg(A_MFSPR,r,r2));
@@ -1628,15 +1604,6 @@ const
         r,r2,rsp:Tregister;
         regcounter2: Tsuperregister;
       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.number:=NR_R0;
         rsp.enum:=R_INTREGISTER;
@@ -2565,7 +2532,13 @@ begin
 end.
 {
   $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
 
   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 getintparaloc(list: taasmoutput; nr : longint) : tparalocation;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;
           function getfuncretparaloc(p : tabstractprocdef) : tparalocation;override;
        end;
@@ -90,6 +92,25 @@ unit cpupara;
            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;
 
       begin
@@ -364,7 +385,13 @@ begin
 end.
 {
   $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
       the crc of the ppu files can change between interface and
       implementation)

+ 45 - 7
compiler/powerpc/rgcpu.pas

@@ -37,6 +37,8 @@ unit rgcpu;
        trgcpu = class(trgobj)
          function getexplicitregisterint(list: taasmoutput; reg: Tnewregister): 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;
                                          var saved:Tpushedsavedint;
                                          const s:Tsupregset);override;
@@ -46,6 +48,7 @@ unit rgcpu;
          procedure cleartempgen; override;
         private
          usedpararegs: Tsupregset;
+         usedparafpuregs: tregisterset;
        end;
 
   implementation
@@ -55,8 +58,6 @@ unit rgcpu;
 
     function trgcpu.getexplicitregisterint(list: taasmoutput; reg: Tnewregister): tregister;
 
-    var r:Tregister;
-
       begin
         if ((reg shr 8) in [RS_R0,RS_R2..RS_R12]) and
            not((reg shr 8) in is_reg_var_int) then
@@ -64,10 +65,9 @@ unit rgcpu;
             if (reg shr 8) in usedpararegs then
               internalerror(2003060701);
             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
         else result := inherited getexplicitregisterint(list,reg);
       end;
@@ -89,6 +89,37 @@ unit rgcpu;
       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;
                                          var saved:Tpushedsavedint;
                                          const s:Tsupregset);
@@ -116,6 +147,7 @@ unit rgcpu;
       begin
         inherited cleartempgen;
         usedpararegs := [];
+        usedparafpuregs := [];
       end;
 
 initialization
@@ -124,7 +156,13 @@ end.
 
 {
   $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
     * ppc get/freeintparaloc now check whether the parameter regs are
       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)
           }
-          function getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;
+          function getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;virtual;
 
           {# Deallocate any kind of register }
           procedure ungetregister(list: taasmoutput; r : tregister); virtual;
@@ -2463,7 +2463,13 @@ end.
 
 {
   $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
     * makeregsize only accepts newregister
     * i386 uses generic tcgnotnode,tcgunaryminus