Browse Source

* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading

peter 21 years ago
parent
commit
64b0a0eadf

+ 35 - 18
compiler/cg64f32.pas

@@ -72,10 +72,10 @@ unit cg64f32;
         procedure a_op64_loc_reg(list : taasmoutput;op:TOpCG;const l : tlocation;reg : tregister64);override;
         procedure a_op64_loc_reg(list : taasmoutput;op:TOpCG;const l : tlocation;reg : tregister64);override;
         procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;value : qword;const ref : treference);override;
         procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;value : qword;const ref : treference);override;
 
 
-        procedure a_param64_reg(list : taasmoutput;reg : tregister64;const locpara : tparalocation);override;
-        procedure a_param64_const(list : taasmoutput;value : qword;const locpara : tparalocation);override;
-        procedure a_param64_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);override;
-        procedure a_param64_loc(list : taasmoutput;const l : tlocation;const locpara : tparalocation);override;
+        procedure a_param64_reg(list : taasmoutput;reg : tregister64;var locpara : tparalocation;alloctemp:boolean);override;
+        procedure a_param64_const(list : taasmoutput;value : qword;var locpara : tparalocation;alloctemp:boolean);override;
+        procedure a_param64_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);override;
+        procedure a_param64_loc(list : taasmoutput;const l : tlocation;var locpara : tparalocation;alloctemp:boolean);override;
 
 
         {# This routine tries to optimize the a_op64_const_reg operation, by
         {# This routine tries to optimize the a_op64_const_reg operation, by
            removing superfluous opcodes. Returns TRUE if normal processing
            removing superfluous opcodes. Returns TRUE if normal processing
@@ -452,31 +452,43 @@ unit cg64f32;
       end;
       end;
 
 
 
 
-    procedure tcg64f32.a_param64_reg(list : taasmoutput;reg : tregister64;const locpara : tparalocation);
+    procedure tcg64f32.a_param64_reg(list : taasmoutput;reg : tregister64;var locpara : tparalocation;alloctemp:boolean);
       var
       var
         tmplochi,tmploclo: tparalocation;
         tmplochi,tmploclo: tparalocation;
       begin
       begin
+        if alloctemp then
+          paramanager.alloctempparaloc(list,locpara)
+        else
+          paramanager.allocparaloc(list,locpara);
         paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
         paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
-        cg.a_param_reg(list,OS_32,reg.reghi,tmplochi);
-        cg.a_param_reg(list,OS_32,reg.reglo,tmploclo);
+        cg.a_param_reg(list,OS_32,reg.reghi,tmplochi,false);
+        cg.a_param_reg(list,OS_32,reg.reglo,tmploclo,false);
       end;
       end;
 
 
 
 
-    procedure tcg64f32.a_param64_const(list : taasmoutput;value : qword;const locpara : tparalocation);
+    procedure tcg64f32.a_param64_const(list : taasmoutput;value : qword;var locpara : tparalocation;alloctemp:boolean);
       var
       var
         tmplochi,tmploclo: tparalocation;
         tmplochi,tmploclo: tparalocation;
       begin
       begin
+        if alloctemp then
+          paramanager.alloctempparaloc(list,locpara)
+        else
+          paramanager.allocparaloc(list,locpara);
         paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
         paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
-        cg.a_param_const(list,OS_32,hi(value),tmplochi);
-        cg.a_param_const(list,OS_32,lo(value),tmploclo);
+        cg.a_param_const(list,OS_32,hi(value),tmplochi,false);
+        cg.a_param_const(list,OS_32,lo(value),tmploclo,false);
       end;
       end;
 
 
 
 
-    procedure tcg64f32.a_param64_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
+    procedure tcg64f32.a_param64_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);
       var
       var
         tmprefhi,tmpreflo : treference;
         tmprefhi,tmpreflo : treference;
         tmploclo,tmplochi : tparalocation;
         tmploclo,tmplochi : tparalocation;
       begin
       begin
+        if alloctemp then
+          paramanager.alloctempparaloc(list,locpara)
+        else
+          paramanager.allocparaloc(list,locpara);
         paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
         paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
         tmprefhi:=r;
         tmprefhi:=r;
         tmpreflo:=r;
         tmpreflo:=r;
@@ -484,22 +496,22 @@ unit cg64f32;
           inc(tmpreflo.offset,4)
           inc(tmpreflo.offset,4)
         else
         else
           inc(tmprefhi.offset,4);
           inc(tmprefhi.offset,4);
-        cg.a_param_ref(list,OS_32,tmprefhi,tmplochi);
-        cg.a_param_ref(list,OS_32,tmpreflo,tmploclo);
+        cg.a_param_ref(list,OS_32,tmprefhi,tmplochi,false);
+        cg.a_param_ref(list,OS_32,tmpreflo,tmploclo,false);
       end;
       end;
 
 
 
 
-    procedure tcg64f32.a_param64_loc(list : taasmoutput;const l:tlocation;const locpara : tparalocation);
+    procedure tcg64f32.a_param64_loc(list : taasmoutput;const l:tlocation;var locpara : tparalocation;alloctemp:boolean);
       begin
       begin
         case l.loc of
         case l.loc of
           LOC_REGISTER,
           LOC_REGISTER,
           LOC_CREGISTER :
           LOC_CREGISTER :
-            a_param64_reg(list,l.register64,locpara);
+            a_param64_reg(list,l.register64,locpara,alloctemp);
           LOC_CONSTANT :
           LOC_CONSTANT :
-            a_param64_const(list,l.valueqword,locpara);
+            a_param64_const(list,l.valueqword,locpara,alloctemp);
           LOC_CREFERENCE,
           LOC_CREFERENCE,
           LOC_REFERENCE :
           LOC_REFERENCE :
-            a_param64_ref(list,l.reference,locpara);
+            a_param64_ref(list,l.reference,locpara,alloctemp);
           else
           else
             internalerror(200203287);
             internalerror(200203287);
         end;
         end;
@@ -761,7 +773,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.52  2003-10-10 17:48:13  peter
+  Revision 1.53  2003-12-03 23:13:19  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.52  2003/10/10 17:48:13  peter
     * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
     * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
     * tregisteralloctor renamed to trgobj
     * tregisteralloctor renamed to trgobj
     * removed rgobj from a lot of units
     * removed rgobj from a lot of units

+ 58 - 67
compiler/cgobj.pas

@@ -117,7 +117,7 @@ unit cgobj;
              @param(r register source of the operand)
              @param(r register source of the operand)
              @param(locpara where the parameter will be stored)
              @param(locpara where the parameter will be stored)
           }
           }
-          procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);virtual;
+          procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;var locpara : tparalocation;alloctemp:boolean);virtual;
           {# Pass a parameter, which is a constant, to a routine.
           {# Pass a parameter, which is a constant, to a routine.
 
 
              A generic version is provided. This routine should
              A generic version is provided. This routine should
@@ -128,7 +128,7 @@ unit cgobj;
              @param(a value of constant to send)
              @param(a value of constant to send)
              @param(locpara where the parameter will be stored)
              @param(locpara where the parameter will be stored)
           }
           }
-          procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);virtual;
+          procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;var locpara : tparalocation;alloctemp:boolean);virtual;
           {# Pass the value of a parameter, which is located in memory, to a routine.
           {# Pass the value of a parameter, which is located in memory, to a routine.
 
 
              A generic version is provided. This routine should
              A generic version is provided. This routine should
@@ -139,7 +139,7 @@ unit cgobj;
              @param(r Memory reference of value to send)
              @param(r Memory reference of value to send)
              @param(locpara where the parameter will be stored)
              @param(locpara where the parameter will be stored)
           }
           }
-          procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);virtual;
+          procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;var locpara : tparalocation;alloctemp:boolean);virtual;
           {# Pass the value of a parameter, which can be located either in a register or memory location,
           {# Pass the value of a parameter, which can be located either in a register or memory location,
              to a routine.
              to a routine.
 
 
@@ -149,7 +149,7 @@ unit cgobj;
              @param(nr parameter number (starting from one) of routine (from left to right))
              @param(nr parameter number (starting from one) of routine (from left to right))
              @param(locpara where the parameter will be stored)
              @param(locpara where the parameter will be stored)
           }
           }
-          procedure a_param_loc(list : taasmoutput;const l : tlocation;const locpara : tparalocation);
+          procedure a_param_loc(list : taasmoutput;const l : tlocation;var locpara : tparalocation;alloctemp:boolean);
           {# Pass the address of a reference to a routine. This routine
           {# Pass the address of a reference to a routine. This routine
              will calculate the address of the reference, and pass this
              will calculate the address of the reference, and pass this
              calculated address as a parameter.
              calculated address as a parameter.
@@ -161,10 +161,10 @@ unit cgobj;
              @param(r reference to get address from)
              @param(r reference to get address from)
              @param(nr parameter number (starting from one) of routine (from left to right))
              @param(nr parameter number (starting from one) of routine (from left to right))
           }
           }
-          procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);virtual;
+          procedure a_paramaddr_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);virtual;
 
 
           { Copies a whole memory block to the stack, the locpara must be a memory location }
           { Copies a whole memory block to the stack, the locpara must be a memory location }
-          procedure a_param_copy_ref(list : taasmoutput;size : qword;const r : treference;const locpara : tparalocation);
+          procedure a_param_copy_ref(list : taasmoutput;size : qword;const r : treference;var locpara : tparalocation;alloctemp:boolean);
           { Remarks:
           { Remarks:
             * If a method specifies a size you have only to take care
             * If a method specifies a size you have only to take care
               of that number of bits, i.e. load_const_reg with OP_8 must
               of that number of bits, i.e. load_const_reg with OP_8 must
@@ -475,10 +475,10 @@ unit cgobj;
         procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : qword;regsrc,regdst : tregister64);virtual;
         procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : qword;regsrc,regdst : tregister64);virtual;
         procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);virtual;
         procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);virtual;
 
 
-        procedure a_param64_reg(list : taasmoutput;reg64 : tregister64;const loc : tparalocation);virtual;abstract;
-        procedure a_param64_const(list : taasmoutput;value : qword;const loc : tparalocation);virtual;abstract;
-        procedure a_param64_ref(list : taasmoutput;const r : treference;const loc : tparalocation);virtual;abstract;
-        procedure a_param64_loc(list : taasmoutput;const l : tlocation;const loc : tparalocation);virtual;abstract;
+        procedure a_param64_reg(list : taasmoutput;reg64 : tregister64;var loc : tparalocation;alloctemp:boolean);virtual;abstract;
+        procedure a_param64_const(list : taasmoutput;value : qword;var loc : tparalocation;alloctemp:boolean);virtual;abstract;
+        procedure a_param64_ref(list : taasmoutput;const r : treference;var loc : tparalocation;alloctemp:boolean);virtual;abstract;
+        procedure a_param64_loc(list : taasmoutput;const l : tlocation;var loc : tparalocation;alloctemp:boolean);virtual;abstract;
 
 
         {
         {
              This routine tries to optimize the const_reg opcode, and should be
              This routine tries to optimize the const_reg opcode, and should be
@@ -600,10 +600,14 @@ implementation
           for better code generation these methods should be overridden
           for better code generation these methods should be overridden
 ******************************************************************************}
 ******************************************************************************}
 
 
-    procedure tcg.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);
+    procedure tcg.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;var locpara : tparalocation;alloctemp:boolean);
       var
       var
          ref : treference;
          ref : treference;
       begin
       begin
+         if alloctemp then
+           paramanager.alloctempparaloc(list,locpara)
+         else
+           paramanager.allocparaloc(list,locpara);
          case locpara.loc of
          case locpara.loc of
             LOC_REGISTER,LOC_CREGISTER:
             LOC_REGISTER,LOC_CREGISTER:
               a_load_reg_reg(list,size,locpara.size,r,locpara.register);
               a_load_reg_reg(list,size,locpara.size,r,locpara.register);
@@ -619,8 +623,8 @@ implementation
          end;
          end;
       end;
       end;
 
 
-    procedure tcg.a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);
 
 
+    procedure tcg.a_param_const(list : taasmoutput;size : tcgsize;a : aword;var locpara : tparalocation;alloctemp:boolean);
       var
       var
          hr : tregister;
          hr : tregister;
 
 
@@ -628,49 +632,50 @@ implementation
          hr:=getintregister(list,size);
          hr:=getintregister(list,size);
          a_load_const_reg(list,size,a,hr);
          a_load_const_reg(list,size,a,hr);
          ungetregister(list,hr);
          ungetregister(list,hr);
-         a_param_reg(list,size,hr,locpara);
+         a_param_reg(list,size,hr,locpara,alloctemp);
       end;
       end;
 
 
-    procedure tcg.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);
+
+    procedure tcg.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;var locpara : tparalocation;alloctemp:boolean);
       var
       var
          hr : tregister;
          hr : tregister;
       begin
       begin
          hr:=getintregister(list,size);
          hr:=getintregister(list,size);
          a_load_ref_reg(list,size,size,r,hr);
          a_load_ref_reg(list,size,size,r,hr);
          ungetregister(list,hr);
          ungetregister(list,hr);
-         a_param_reg(list,size,hr,locpara);
+         a_param_reg(list,size,hr,locpara,alloctemp);
       end;
       end;
 
 
 
 
-    procedure tcg.a_param_loc(list : taasmoutput;const l:tlocation;const locpara : tparalocation);
+    procedure tcg.a_param_loc(list : taasmoutput;const l:tlocation;var locpara : tparalocation;alloctemp:boolean);
       begin
       begin
         case l.loc of
         case l.loc of
           LOC_REGISTER,
           LOC_REGISTER,
           LOC_CREGISTER :
           LOC_CREGISTER :
-            a_param_reg(list,l.size,l.register,locpara);
+            a_param_reg(list,l.size,l.register,locpara,alloctemp);
           LOC_CONSTANT :
           LOC_CONSTANT :
-            a_param_const(list,l.size,l.value,locpara);
+            a_param_const(list,l.size,l.value,locpara,alloctemp);
           LOC_CREFERENCE,
           LOC_CREFERENCE,
           LOC_REFERENCE :
           LOC_REFERENCE :
-            a_param_ref(list,l.size,l.reference,locpara);
+            a_param_ref(list,l.size,l.reference,locpara,alloctemp);
         else
         else
           internalerror(2002032211);
           internalerror(2002032211);
         end;
         end;
       end;
       end;
 
 
 
 
-    procedure tcg.a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
+    procedure tcg.a_paramaddr_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);
       var
       var
          hr : tregister;
          hr : tregister;
       begin
       begin
          hr:=getaddressregister(list);
          hr:=getaddressregister(list);
          a_loadaddr_ref_reg(list,r,hr);
          a_loadaddr_ref_reg(list,r,hr);
          ungetregister(list,hr);
          ungetregister(list,hr);
-         a_param_reg(list,OS_ADDR,hr,locpara);
+         a_param_reg(list,OS_ADDR,hr,locpara,alloctemp);
       end;
       end;
 
 
 
 
-    procedure tcg.a_param_copy_ref(list : taasmoutput;size : qword;const r : treference;const locpara : tparalocation);
+    procedure tcg.a_param_copy_ref(list : taasmoutput;size : qword;const r : treference;var locpara : tparalocation;alloctemp:boolean);
       var
       var
         ref : treference;
         ref : treference;
       begin
       begin
@@ -1273,17 +1278,14 @@ implementation
         paraloc1:=paramanager.getintparaloc(pocall_default,1);
         paraloc1:=paramanager.getintparaloc(pocall_default,1);
         paraloc2:=paramanager.getintparaloc(pocall_default,2);
         paraloc2:=paramanager.getintparaloc(pocall_default,2);
         paraloc3:=paramanager.getintparaloc(pocall_default,3);
         paraloc3:=paramanager.getintparaloc(pocall_default,3);
-        paramanager.allocparaloc(list,paraloc3);
-        a_paramaddr_ref(list,dest,paraloc3);
-        paramanager.allocparaloc(list,paraloc2);
+        a_paramaddr_ref(list,dest,paraloc3,false);
         if loadref then
         if loadref then
-          a_param_ref(list,OS_ADDR,source,paraloc2)
+          a_param_ref(list,OS_ADDR,source,paraloc2,false)
         else
         else
-          a_paramaddr_ref(list,source,paraloc2);
+          a_paramaddr_ref(list,source,paraloc2,false);
         if delsource then
         if delsource then
          reference_release(list,source);
          reference_release(list,source);
-        paramanager.allocparaloc(list,paraloc1);
-        a_param_const(list,OS_INT,len,paraloc1);
+        a_param_const(list,OS_INT,len,paraloc1,false);
         paramanager.freeparaloc(list,paraloc3);
         paramanager.freeparaloc(list,paraloc3);
         paramanager.freeparaloc(list,paraloc2);
         paramanager.freeparaloc(list,paraloc2);
         paramanager.freeparaloc(list,paraloc1);
         paramanager.freeparaloc(list,paraloc1);
@@ -1317,8 +1319,7 @@ implementation
          if incrfunc<>'' then
          if incrfunc<>'' then
           begin
           begin
             { these functions get the pointer by value }
             { these functions get the pointer by value }
-            paramanager.allocparaloc(list,paraloc1);
-            a_param_ref(list,OS_ADDR,ref,paraloc1);
+            a_param_ref(list,OS_ADDR,ref,paraloc1,false);
             paramanager.freeparaloc(list,paraloc1);
             paramanager.freeparaloc(list,paraloc1);
             allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             a_call_name(list,incrfunc);
             a_call_name(list,incrfunc);
@@ -1327,13 +1328,11 @@ implementation
          else
          else
           begin
           begin
             reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
             reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
-            paramanager.allocparaloc(list,paraloc2);
-            a_paramaddr_ref(list,href,paraloc2);
-            paramanager.allocparaloc(list,paraloc1);
+            a_paramaddr_ref(list,href,paraloc2,false);
             if loadref then
             if loadref then
-              a_param_ref(list,OS_ADDR,ref,paraloc1)
+              a_param_ref(list,OS_ADDR,ref,paraloc1,false)
             else
             else
-              a_paramaddr_ref(list,ref,paraloc1);
+              a_paramaddr_ref(list,ref,paraloc1,false);
             paramanager.freeparaloc(list,paraloc1);
             paramanager.freeparaloc(list,paraloc1);
             paramanager.freeparaloc(list,paraloc2);
             paramanager.freeparaloc(list,paraloc2);
             allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -1372,14 +1371,12 @@ implementation
             if needrtti then
             if needrtti then
              begin
              begin
                reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
                reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
-               paramanager.allocparaloc(list,paraloc2);
-               a_paramaddr_ref(list,href,paraloc2);
+               a_paramaddr_ref(list,href,paraloc2,false);
              end;
              end;
-            paramanager.allocparaloc(list,paraloc1);
             if loadref then
             if loadref then
-              a_param_ref(list,OS_ADDR,ref,paraloc1)
+              a_param_ref(list,OS_ADDR,ref,paraloc1,false)
             else
             else
-              a_paramaddr_ref(list,ref,paraloc1);
+              a_paramaddr_ref(list,ref,paraloc1,false);
             paramanager.freeparaloc(list,paraloc1);
             paramanager.freeparaloc(list,paraloc1);
             if needrtti then
             if needrtti then
               paramanager.freeparaloc(list,paraloc2);
               paramanager.freeparaloc(list,paraloc2);
@@ -1390,13 +1387,11 @@ implementation
          else
          else
           begin
           begin
             reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
             reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
-            paramanager.allocparaloc(list,paraloc2);
-            a_paramaddr_ref(list,href,paraloc2);
-            paramanager.allocparaloc(list,paraloc1);
+            a_paramaddr_ref(list,href,paraloc2,false);
             if loadref then
             if loadref then
-              a_param_ref(list,OS_ADDR,ref,paraloc1)
+              a_param_ref(list,OS_ADDR,ref,paraloc1,false)
             else
             else
-              a_paramaddr_ref(list,ref,paraloc1);
+              a_paramaddr_ref(list,ref,paraloc1,false);
             paramanager.freeparaloc(list,paraloc1);
             paramanager.freeparaloc(list,paraloc1);
             paramanager.freeparaloc(list,paraloc2);
             paramanager.freeparaloc(list,paraloc2);
             allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -1420,13 +1415,11 @@ implementation
          else
          else
            begin
            begin
               reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
               reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
-              paramanager.allocparaloc(list,paraloc2);
-              a_paramaddr_ref(list,href,paraloc2);
-              paramanager.allocparaloc(list,paraloc1);
+              a_paramaddr_ref(list,href,paraloc2,false);
               if loadref then
               if loadref then
-                a_param_ref(list,OS_ADDR,ref,paraloc1)
+                a_param_ref(list,OS_ADDR,ref,paraloc1,false)
               else
               else
-                a_paramaddr_ref(list,ref,paraloc1);
+                a_paramaddr_ref(list,ref,paraloc1,false);
               paramanager.freeparaloc(list,paraloc1);
               paramanager.freeparaloc(list,paraloc1);
               paramanager.freeparaloc(list,paraloc2);
               paramanager.freeparaloc(list,paraloc2);
               allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -1450,13 +1443,11 @@ implementation
          else
          else
            begin
            begin
               reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
               reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
-              paramanager.allocparaloc(list,paraloc2);
-              a_paramaddr_ref(list,href,paraloc2);
-              paramanager.allocparaloc(list,paraloc1);
+              a_paramaddr_ref(list,href,paraloc2,false);
               if loadref then
               if loadref then
-                a_param_ref(list,OS_ADDR,ref,paraloc1)
+                a_param_ref(list,OS_ADDR,ref,paraloc1,false)
               else
               else
-                a_paramaddr_ref(list,ref,paraloc1);
+                a_paramaddr_ref(list,ref,paraloc1,false);
               paramanager.freeparaloc(list,paraloc1);
               paramanager.freeparaloc(list,paraloc1);
               paramanager.freeparaloc(list,paraloc2);
               paramanager.freeparaloc(list,paraloc2);
               allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -1581,8 +1572,7 @@ implementation
         paraloc1 : tparalocation;
         paraloc1 : tparalocation;
       begin
       begin
          paraloc1:=paramanager.getintparaloc(pocall_default,1);
          paraloc1:=paramanager.getintparaloc(pocall_default,1);
-         paramanager.allocparaloc(list,paraloc1);
-         a_param_const(list,OS_32,stackframesize,paraloc1);
+         a_param_const(list,OS_32,stackframesize,paraloc1,false);
          paramanager.freeparaloc(list,paraloc1);
          paramanager.freeparaloc(list,paraloc1);
          { No register saving needed, saveregisters is used }
          { No register saving needed, saveregisters is used }
          a_call_name(list,'FPC_STACKCHECK');
          a_call_name(list,'FPC_STACKCHECK');
@@ -1612,8 +1602,7 @@ implementation
            objectlibrary.getlabel(oklabel);
            objectlibrary.getlabel(oklabel);
            a_cmp_const_reg_label(list,OS_ADDR,OC_NE,0,reg,oklabel);
            a_cmp_const_reg_label(list,OS_ADDR,OC_NE,0,reg,oklabel);
            paraloc1:=paramanager.getintparaloc(pocall_default,1);
            paraloc1:=paramanager.getintparaloc(pocall_default,1);
-           paramanager.allocparaloc(list,paraloc1);
-           a_param_const(list,OS_INT,210,paraloc1);
+           a_param_const(list,OS_INT,210,paraloc1,false);
            paramanager.freeparaloc(list,paraloc1);
            paramanager.freeparaloc(list,paraloc1);
            a_call_name(list,'FPC_HANDLEERROR');
            a_call_name(list,'FPC_HANDLEERROR');
            a_label(list,oklabel);
            a_label(list,oklabel);
@@ -1631,10 +1620,8 @@ implementation
         if (cs_check_object in aktlocalswitches) then
         if (cs_check_object in aktlocalswitches) then
          begin
          begin
            reference_reset_symbol(hrefvmt,objectlibrary.newasmsymboldata(objdef.vmt_mangledname),0);
            reference_reset_symbol(hrefvmt,objectlibrary.newasmsymboldata(objdef.vmt_mangledname),0);
-           paramanager.allocparaloc(list,paraloc2);
-           a_paramaddr_ref(list,hrefvmt,paraloc2);
-           paramanager.allocparaloc(list,paraloc1);
-           a_param_reg(list,OS_ADDR,reg,paraloc1);
+           a_paramaddr_ref(list,hrefvmt,paraloc2,false);
+           a_param_reg(list,OS_ADDR,reg,paraloc1,false);
            paramanager.freeparaloc(list,paraloc1);
            paramanager.freeparaloc(list,paraloc1);
            paramanager.freeparaloc(list,paraloc2);
            paramanager.freeparaloc(list,paraloc2);
            { No register saving needed, saveregisters is used }
            { No register saving needed, saveregisters is used }
@@ -1643,8 +1630,7 @@ implementation
         else
         else
          if (cs_check_range in aktlocalswitches) then
          if (cs_check_range in aktlocalswitches) then
           begin
           begin
-            paramanager.allocparaloc(list,paraloc1);
-            a_param_reg(list,OS_ADDR,reg,paraloc1);
+            a_param_reg(list,OS_ADDR,reg,paraloc1,false);
             paramanager.freeparaloc(list,paraloc1);
             paramanager.freeparaloc(list,paraloc1);
             { No register saving needed, saveregisters is used }
             { No register saving needed, saveregisters is used }
             a_call_name(list,'FPC_CHECK_OBJECT');
             a_call_name(list,'FPC_CHECK_OBJECT');
@@ -1817,7 +1803,12 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.134  2003-11-05 23:05:13  florian
+  Revision 1.135  2003-12-03 23:13:19  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.134  2003/11/05 23:05:13  florian
     * elesize of g_copyvaluepara_openarray changed
     * elesize of g_copyvaluepara_openarray changed
     + g_releaesvaluepara_openarray added
     + g_releaesvaluepara_openarray added
 
 

+ 7 - 13
compiler/i386/cpupara.pas

@@ -129,16 +129,6 @@ unit cpupara;
               end;
               end;
             end;
             end;
         end;
         end;
-        if calloption=pocall_register then
-          begin
-            case def.deftype of
-              floatdef :
-                begin
-                  result:=true;
-                  exit;
-                end;
-            end;
-          end;
         result:=inherited push_addr_param(varspez,def,calloption);
         result:=inherited push_addr_param(varspez,def,calloption);
       end;
       end;
 
 
@@ -419,7 +409,6 @@ unit cpupara;
             if (parareg<=high(parasupregs)) and
             if (parareg<=high(parasupregs)) and
                not(
                not(
                    is_64bit or
                    is_64bit or
-                   (hp.paratype.def.deftype=floatdef) or
                    ((hp.paratype.def.deftype in [floatdef,recorddef,arraydef]) and
                    ((hp.paratype.def.deftype in [floatdef,recorddef,arraydef]) and
                     (not pushaddr))
                     (not pushaddr))
                   ) then
                   ) then
@@ -462,7 +451,7 @@ unit cpupara;
                 hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
                 hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
                 if side=calleeside then
                 if side=calleeside then
                   inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
                   inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
-              end;    
+              end;
             hp:=tparaitem(hp.next);
             hp:=tparaitem(hp.next);
           end;
           end;
         { We need to return the size allocated }
         { We need to return the size allocated }
@@ -498,7 +487,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.46  2003-12-01 18:44:15  peter
+  Revision 1.47  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.46  2003/12/01 18:44:15  peter
     * fixed some crashes
     * fixed some crashes
     * fixed varargs and register calling probs
     * fixed varargs and register calling probs
 
 

+ 10 - 9
compiler/i386/n386add.pas

@@ -356,8 +356,7 @@ interface
                          end
                          end
                        else
                        else
                          begin
                          begin
-                           paramanager.allocparaloc(exprasmlist,paraloc2);
-                           cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraloc2);
+                           cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraloc2,false);
                          end;
                          end;
                        secondpass(right);
                        secondpass(right);
                        location_release(exprasmlist,right.location);
                        location_release(exprasmlist,right.location);
@@ -368,21 +367,18 @@ interface
                          end
                          end
                        else
                        else
                          begin
                          begin
-                           paramanager.allocparaloc(exprasmlist,paraloc1);
-                           cg.a_paramaddr_ref(exprasmlist,right.location.reference,paraloc1);
+                           cg.a_paramaddr_ref(exprasmlist,right.location.reference,paraloc1,false);
                          end;
                          end;
                        { push parameters }
                        { push parameters }
                        if paraloc1.loc=LOC_REGISTER then
                        if paraloc1.loc=LOC_REGISTER then
                          begin
                          begin
                            cg.ungetregister(exprasmlist,hregister2);
                            cg.ungetregister(exprasmlist,hregister2);
-                           paramanager.allocparaloc(exprasmlist,paraloc2);
-                           cg.a_param_reg(exprasmlist,OS_ADDR,hregister2,paraloc2);
+                           cg.a_param_reg(exprasmlist,OS_ADDR,hregister2,paraloc2,false);
                          end;
                          end;
                        if paraloc2.loc=LOC_REGISTER then
                        if paraloc2.loc=LOC_REGISTER then
                          begin
                          begin
                            cg.ungetregister(exprasmlist,hregister1);
                            cg.ungetregister(exprasmlist,hregister1);
-                           paramanager.allocparaloc(exprasmlist,paraloc1);
-                           cg.a_param_reg(exprasmlist,OS_ADDR,hregister1,paraloc1);
+                           cg.a_param_reg(exprasmlist,OS_ADDR,hregister1,paraloc1,false);
                          end;
                          end;
                        paramanager.freeparaloc(exprasmlist,paraloc1);
                        paramanager.freeparaloc(exprasmlist,paraloc1);
                        paramanager.freeparaloc(exprasmlist,paraloc2);
                        paramanager.freeparaloc(exprasmlist,paraloc2);
@@ -1495,7 +1491,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.86  2003-10-17 14:38:32  peter
+  Revision 1.87  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.86  2003/10/17 14:38:32  peter
     * 64k registers supported
     * 64k registers supported
     * fixed some memory leaks
     * fixed some memory leaks
 
 

+ 32 - 79
compiler/i386/n386cnv.pas

@@ -65,8 +65,8 @@ implementation
       symconst,symdef,aasmbase,aasmtai,aasmcpu,
       symconst,symdef,aasmbase,aasmtai,aasmcpu,
       cgbase,
       cgbase,
       ncon,ncal,ncnv,
       ncon,ncal,ncnv,
-      cpubase,
-      cgobj,cga,cgx86;
+      cpubase,tgobj,
+      cgobj,cga,cgx86,ncgutil;
 
 
 
 
     function ti386typeconvnode.first_int_to_real : tnode;
     function ti386typeconvnode.first_int_to_real : tnode;
@@ -85,92 +85,45 @@ implementation
          href : treference;
          href : treference;
          hregister : tregister;
          hregister : tregister;
          l1,l2 : tasmlabel;
          l1,l2 : tasmlabel;
-         freereg : boolean;
-
       begin
       begin
          location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
          location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
-         hregister:=NR_NO;
-         freereg:=false;
 
 
-         { for u32bit a solution is to push $0 and to load a comp }
-         { does this first, it destroys maybe EDI }
-         if torddef(left.resulttype.def).typ=u32bit then
-          exprasmlist.concat(taicpu.op_const(A_PUSH,S_L,0));
+         { We need to load from a reference }
+         location_force_mem(exprasmlist,left.location);
 
 
-         case left.location.loc of
-           LOC_REGISTER,
-           LOC_CREGISTER :
-             begin
-               case left.location.size of
-                 OS_64,OS_S64 :
-                   begin
-                     exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,left.location.registerhigh));
-                     hregister:=left.location.registerlow;
-                   end;
-                 OS_32,OS_S32 :
-                   hregister:=left.location.register;
-                 else
-                   begin
-                     hregister:=cg.getintregister(exprasmlist,OS_32);
-                     freereg:=true;
-                     cg.a_load_reg_reg(exprasmlist,left.location.size,OS_32,left.location.register,hregister);
-                   end;
-               end;
-             end;
-           LOC_REFERENCE,
-           LOC_CREFERENCE :
-             begin
-               hregister:=cg.getintregister(exprasmlist,OS_INT);
-               freereg:=true;
-               if left.location.size in [OS_64,OS_S64] then
-                begin
-                  href:=left.location.reference;
-                  inc(href.offset,4);
-                  cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,href,hregister);
-                  exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,hregister));
-                  cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,left.location.reference,hregister);
-                end
-               else
-                cg.a_load_ref_reg(exprasmlist,left.location.size,OS_INT,left.location.reference,hregister);
-             end;
-           else
-             internalerror(2002032218);
-         end;
-         location_release(exprasmlist,left.location);
-         location_freetemp(exprasmlist,left.location);
+         { For u32bit we need to load it as comp and need to
+           make it 64bits }
+         if (torddef(left.resulttype.def).typ=u32bit) then
+           begin
+             tg.GetTemp(exprasmlist,8,tt_normal,href);
+             cg.g_concatcopy(exprasmlist,left.location.reference,href,4,true,false);
+             inc(href.offset,4);
+             cg.a_load_const_ref(exprasmlist,OS_32,0,href);
+             dec(href.offset,4);
+             left.location.reference:=href;
+           end;
 
 
-         { for 64 bit integers, the high dword is already pushed }
-         exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,hregister));
-         if freereg then
-           cg.ungetregister(exprasmlist,hregister);
-         reference_reset_base(href,NR_ESP,0);
+         { Load from reference to fpu reg }
+         location_release(exprasmlist,left.location);
          case torddef(left.resulttype.def).typ of
          case torddef(left.resulttype.def).typ of
-           u32bit:
-             begin
-                emit_ref(A_FILD,S_IQ,href);
-                emit_const_reg(A_ADD,S_L,8,NR_ESP);
-             end;
+           u32bit,
            scurrency,
            scurrency,
            s64bit:
            s64bit:
-             begin
-                emit_ref(A_FILD,S_IQ,href);
-                emit_const_reg(A_ADD,S_L,8,NR_ESP);
-             end;
+             exprasmlist.concat(taicpu.op_ref(A_FILD,S_IQ,left.location.reference));
            u64bit:
            u64bit:
              begin
              begin
                 { unsigned 64 bit ints are harder to handle: }
                 { unsigned 64 bit ints are harder to handle: }
                 { we load bits 0..62 and then check bit 63:  }
                 { we load bits 0..62 and then check bit 63:  }
                 { if it is 1 then we add $80000000 000000000 }
                 { if it is 1 then we add $80000000 000000000 }
                 { as double                                  }
                 { as double                                  }
-                inc(href.offset,4);
+                inc(left.location.reference.offset,4);
                 hregister:=cg.getintregister(exprasmlist,OS_32);
                 hregister:=cg.getintregister(exprasmlist,OS_32);
-                cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,href,hregister);
-                reference_reset_base(href,NR_ESP,4);
-                emit_const_ref(A_AND,S_L,$7fffffff,href);
+                cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,left.location.reference,hregister);
+                emit_const_ref(A_AND,S_L,$7fffffff,left.location.reference);
                 emit_const_reg(A_TEST,S_L,longint($80000000),hregister);
                 emit_const_reg(A_TEST,S_L,longint($80000000),hregister);
                 cg.ungetregister(exprasmlist,hregister);
                 cg.ungetregister(exprasmlist,hregister);
-                reference_reset_base(href,NR_ESP,0);
-                emit_ref(A_FILD,S_IQ,href);
+                dec(left.location.reference.offset,4);
+                exprasmlist.concat(taicpu.op_ref(A_FILD,S_IQ,left.location.reference));
                 objectlibrary.getdatalabel(l1);
                 objectlibrary.getdatalabel(l1);
                 objectlibrary.getlabel(l2);
                 objectlibrary.getlabel(l2);
                 cg.a_jmp_flags(exprasmlist,F_E,l2);
                 cg.a_jmp_flags(exprasmlist,F_E,l2);
@@ -181,16 +134,11 @@ implementation
                 reference_reset_symbol(href,l1,0);
                 reference_reset_symbol(href,l1,0);
                 emit_ref(A_FADD,S_FL,href);
                 emit_ref(A_FADD,S_FL,href);
                 cg.a_label(exprasmlist,l2);
                 cg.a_label(exprasmlist,l2);
-                emit_const_reg(A_ADD,S_L,8,NR_ESP);
              end
              end
            else
            else
-             begin
-                emit_ref(A_FILD,S_IL,href);
-                hregister:=cg.getintregister(exprasmlist,OS_32);
-                emit_reg(A_POP,S_L,hregister);
-                cg.ungetregister(exprasmlist,hregister);
-             end;
+             exprasmlist.concat(taicpu.op_ref(A_FILD,S_IL,left.location.reference));
          end;
          end;
+         location_freetemp(exprasmlist,left.location);
          tcgx86(cg).inc_fpu_stack;
          tcgx86(cg).inc_fpu_stack;
          location.register:=NR_ST;
          location.register:=NR_ST;
       end;
       end;
@@ -236,7 +184,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.68  2003-11-04 22:30:15  florian
+  Revision 1.69  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.68  2003/11/04 22:30:15  florian
     + type cast variant<->enum
     + type cast variant<->enum
     * cnv. node second pass uses now as well helper wrappers
     * cnv. node second pass uses now as well helper wrappers
 
 

+ 33 - 31
compiler/ncgcal.pas

@@ -35,7 +35,6 @@ interface
        tcgcallparanode = class(tcallparanode)
        tcgcallparanode = class(tcallparanode)
        private
        private
           tempparaloc : tparalocation;
           tempparaloc : tparalocation;
-          procedure allocate_tempparaloc;
           procedure push_addr_para;
           procedure push_addr_para;
           procedure push_value_para;
           procedure push_value_para;
        public
        public
@@ -99,22 +98,12 @@ implementation
                              TCGCALLPARANODE
                              TCGCALLPARANODE
 *****************************************************************************}
 *****************************************************************************}
 
 
-    procedure tcgcallparanode.allocate_tempparaloc;
-      begin
-         { Allocate (temporary) paralocation }
-         tempparaloc:=paraitem.paraloc[callerside];
-         if (tempparaloc.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER]) then
-           paramanager.alloctempregs(exprasmlist,tempparaloc)
-      end;
-
-
     procedure tcgcallparanode.push_addr_para;
     procedure tcgcallparanode.push_addr_para;
       begin
       begin
         if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
         if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
           internalerror(200304235);
           internalerror(200304235);
         location_release(exprasmlist,left.location);
         location_release(exprasmlist,left.location);
-        allocate_tempparaloc;
-        cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
+        cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc,true);
         inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
         inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
       end;
       end;
 
 
@@ -137,7 +126,6 @@ implementation
         if left.resulttype.def.deftype=floatdef then
         if left.resulttype.def.deftype=floatdef then
          begin
          begin
            location_release(exprasmlist,left.location);
            location_release(exprasmlist,left.location);
-           allocate_tempparaloc;
 {$ifdef i386}
 {$ifdef i386}
            if tempparaloc.loc<>LOC_REFERENCE then
            if tempparaloc.loc<>LOC_REFERENCE then
              internalerror(200309291);
              internalerror(200309291);
@@ -180,7 +168,7 @@ implementation
                            dec(href.offset,2);
                            dec(href.offset,2);
                            dec(size,2);
                            dec(size,2);
                          end;
                          end;
-                        cg.a_param_ref(exprasmlist,cgsize,href,tempparaloc);
+                        cg.a_param_ref(exprasmlist,cgsize,href,tempparaloc,true);
                       end;
                       end;
                    end
                    end
                  else
                  else
@@ -215,7 +203,6 @@ implementation
                   aktcallnode.procdefinition.proccalloption) then
                   aktcallnode.procdefinition.proccalloption) then
             begin
             begin
               location_release(exprasmlist,left.location);
               location_release(exprasmlist,left.location);
-              allocate_tempparaloc;
 {$ifdef i386}
 {$ifdef i386}
               if tempparaloc.loc<>LOC_REFERENCE then
               if tempparaloc.loc<>LOC_REFERENCE then
                 internalerror(200309292);
                 internalerror(200309292);
@@ -249,16 +236,14 @@ implementation
                     if cgsize in [OS_64,OS_S64] then
                     if cgsize in [OS_64,OS_S64] then
                      begin
                      begin
                        inc(tcgcallnode(aktcallnode).pushedparasize,8);
                        inc(tcgcallnode(aktcallnode).pushedparasize,8);
-                       allocate_tempparaloc;
-                       cg64.a_param64_loc(exprasmlist,left.location,tempparaloc);
+                       cg64.a_param64_loc(exprasmlist,left.location,tempparaloc,true);
                        location_release(exprasmlist,left.location);
                        location_release(exprasmlist,left.location);
                      end
                      end
                     else
                     else
                      begin
                      begin
                        location_release(exprasmlist,left.location);
                        location_release(exprasmlist,left.location);
-                       allocate_tempparaloc;
                        inc(tcgcallnode(aktcallnode).pushedparasize,align(tcgsize2size[tempparaloc.size],tempparaloc.alignment));
                        inc(tcgcallnode(aktcallnode).pushedparasize,align(tcgsize2size[tempparaloc.size],tempparaloc.alignment));
-                       cg.a_param_loc(exprasmlist,left.location,tempparaloc);
+                       cg.a_param_loc(exprasmlist,left.location,tempparaloc,true);
                      end;
                      end;
                   end;
                   end;
 {$ifdef SUPPORT_MMX}
 {$ifdef SUPPORT_MMX}
@@ -266,7 +251,6 @@ implementation
                 LOC_CMMXREGISTER:
                 LOC_CMMXREGISTER:
                   begin
                   begin
                      location_release(exprasmlist,left.location);
                      location_release(exprasmlist,left.location);
-                     allocate_tempparaloc;
                      inc(tcgcallnode(aktcallnode).pushedparasize,8);
                      inc(tcgcallnode(aktcallnode).pushedparasize,8);
                      cg.a_parammm_reg(exprasmlist,left.location.register);
                      cg.a_parammm_reg(exprasmlist,left.location.register);
                   end;
                   end;
@@ -291,6 +275,12 @@ implementation
                 (nf_varargs_para in flags)) then
                 (nf_varargs_para in flags)) then
            internalerror(200304242);
            internalerror(200304242);
 
 
+         { Initialize temporary paralocation, only reset register
+           value for register parameters }
+         tempparaloc:=paraitem.paraloc[callerside];
+         if (tempparaloc.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER]) then
+           tempparaloc.register:=NR_NO;
+
          { Skip nothingn nodes which are used after disabling
          { Skip nothingn nodes which are used after disabling
            a parameter }
            a parameter }
          if (left.nodetype<>nothingn) then
          if (left.nodetype<>nothingn) then
@@ -337,8 +327,7 @@ implementation
                     begin
                     begin
                       inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
                       inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
                       location_release(exprasmlist,left.location);
                       location_release(exprasmlist,left.location);
-                      allocate_tempparaloc;
-                      cg.a_param_loc(exprasmlist,left.location,tempparaloc);
+                      cg.a_param_loc(exprasmlist,left.location,tempparaloc,true);
                     end
                     end
                   else
                   else
                     push_addr_para;
                     push_addr_para;
@@ -762,8 +751,10 @@ implementation
                    cg.ungetregister(exprasmlist,pvreg);
                    cg.ungetregister(exprasmlist,pvreg);
 
 
                    cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
                    cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
-                   cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
-                   cg.allocexplicitregisters(exprasmlist,R_SSEREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
+                   if cg.uses_registers(R_FPUREGISTER) then
+                     cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
+                   if cg.uses_registers(R_MMREGISTER) then
+                     cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
 
 
                    { call method }
                    { call method }
                    cg.a_call_reg(exprasmlist,pvreg);
                    cg.a_call_reg(exprasmlist,pvreg);
@@ -779,8 +770,10 @@ implementation
                   freeparas;
                   freeparas;
 
 
                   cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
                   cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
-                  cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
-                  cg.allocexplicitregisters(exprasmlist,R_SSEREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
+                  if cg.uses_registers(R_FPUREGISTER) then
+                    cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
+                  if cg.uses_registers(R_MMREGISTER) then
+                    cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
 
 
                   { Calling interrupt from the same code requires some
                   { Calling interrupt from the same code requires some
                     extra code }
                     extra code }
@@ -815,8 +808,10 @@ implementation
               cg.ungetregister(exprasmlist,pvreg);
               cg.ungetregister(exprasmlist,pvreg);
 
 
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
-              cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
-              cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
+              if cg.uses_registers(R_FPUREGISTER) then
+                cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
+              if cg.uses_registers(R_MMREGISTER) then
+                cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
 
 
               { Calling interrupt from the same code requires some
               { Calling interrupt from the same code requires some
                 extra code }
                 extra code }
@@ -872,8 +867,10 @@ implementation
                  end;
                  end;
              end;
              end;
            end;
            end;
-         cg.deallocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
-         cg.deallocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
+         if cg.uses_registers(R_MMREGISTER) then
+           cg.deallocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
+         if cg.uses_registers(R_FPUREGISTER) then
+           cg.deallocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_free);
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_free);
 
 
          { handle function results }
          { handle function results }
@@ -1119,7 +1116,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.142  2003-12-02 21:23:34  peter
+  Revision 1.143  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.142  2003/12/02 21:23:34  peter
     * exitlabel for inline procs
     * exitlabel for inline procs
 
 
   Revision 1.141  2003/11/23 17:39:33  peter
   Revision 1.141  2003/11/23 17:39:33  peter

+ 18 - 23
compiler/ncgflw.pas

@@ -825,18 +825,16 @@ implementation
               { Push parameters }
               { Push parameters }
               if assigned(right) then
               if assigned(right) then
                 begin
                 begin
-                  paramanager.allocparaloc(exprasmlist,paraloc3);
                   if assigned(frametree) then
                   if assigned(frametree) then
                     begin
                     begin
                       location_release(exprasmlist,frametree.location);
                       location_release(exprasmlist,frametree.location);
-                      cg.a_param_loc(exprasmlist,frametree.location,paraloc3)
+                      cg.a_param_loc(exprasmlist,frametree.location,paraloc3,false)
                     end
                     end
                   else
                   else
-                    cg.a_param_const(exprasmlist,OS_INT,0,paraloc3);
+                    cg.a_param_const(exprasmlist,OS_INT,0,paraloc3,false);
                   { push address }
                   { push address }
                   location_release(exprasmlist,right.location);
                   location_release(exprasmlist,right.location);
-                  paramanager.allocparaloc(exprasmlist,paraloc2);
-                  cg.a_param_loc(exprasmlist,right.location,paraloc2);
+                  cg.a_param_loc(exprasmlist,right.location,paraloc2,false);
                 end
                 end
               else
               else
                 begin
                 begin
@@ -845,18 +843,15 @@ implementation
                    cg.a_label(exprasmlist,a);
                    cg.a_label(exprasmlist,a);
                    reference_reset_symbol(href2,a,0);
                    reference_reset_symbol(href2,a,0);
                    { push current frame }
                    { push current frame }
-                   paramanager.allocparaloc(exprasmlist,paraloc3);
-                   cg.a_param_reg(exprasmlist,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3);
+                   cg.a_param_reg(exprasmlist,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3,false);
                    { push current address }
                    { push current address }
-                   paramanager.allocparaloc(exprasmlist,paraloc2);
                    if target_info.system <> system_powerpc_macos then
                    if target_info.system <> system_powerpc_macos then
-                     cg.a_paramaddr_ref(exprasmlist,href2,paraloc2)
+                     cg.a_paramaddr_ref(exprasmlist,href2,paraloc2,false)
                    else
                    else
-                     cg.a_param_const(exprasmlist,OS_INT,0,paraloc2);
+                     cg.a_param_const(exprasmlist,OS_INT,0,paraloc2,false);
                 end;
                 end;
               location_release(exprasmlist,left.location);
               location_release(exprasmlist,left.location);
-              paramanager.allocparaloc(exprasmlist,paraloc1);
-              cg.a_param_loc(exprasmlist,left.location,paraloc1);
+              cg.a_param_loc(exprasmlist,left.location,paraloc1,false);
               paramanager.freeparaloc(exprasmlist,paraloc1);
               paramanager.freeparaloc(exprasmlist,paraloc1);
               paramanager.freeparaloc(exprasmlist,paraloc2);
               paramanager.freeparaloc(exprasmlist,paraloc2);
               paramanager.freeparaloc(exprasmlist,paraloc3);
               paramanager.freeparaloc(exprasmlist,paraloc3);
@@ -912,8 +907,7 @@ implementation
          cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
          cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          paraloc1:=paramanager.getintparaloc(pocall_default,1);
          paraloc1:=paramanager.getintparaloc(pocall_default,1);
-         paramanager.allocparaloc(exprasmlist,paraloc1);
-         cg.a_param_reg(exprasmlist,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1);
+         cg.a_param_reg(exprasmlist,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1,false);
          paramanager.freeparaloc(exprasmlist,paraloc1);
          paramanager.freeparaloc(exprasmlist,paraloc1);
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
@@ -1021,8 +1015,7 @@ implementation
                 'default handler' flag (=-1)
                 'default handler' flag (=-1)
               }
               }
               paraloc1:=paramanager.getintparaloc(pocall_default,1);
               paraloc1:=paramanager.getintparaloc(pocall_default,1);
-              paramanager.allocparaloc(exprasmlist,paraloc1);
-              cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paraloc1);
+              cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paraloc1,false);
               paramanager.freeparaloc(exprasmlist,paraloc1);
               paramanager.freeparaloc(exprasmlist,paraloc1);
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_CATCHES');
               cg.a_call_name(exprasmlist,'FPC_CATCHES');
@@ -1049,8 +1042,7 @@ implementation
               cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
 
 
               paraloc1:=paramanager.getintparaloc(pocall_default,1);
               paraloc1:=paramanager.getintparaloc(pocall_default,1);
-              paramanager.allocparaloc(exprasmlist,paraloc1);
-              cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
+              cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1,false);
               paramanager.freeparaloc(exprasmlist,paraloc1);
               paramanager.freeparaloc(exprasmlist,paraloc1);
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
               cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
@@ -1186,8 +1178,7 @@ implementation
          { send the vmt parameter }
          { send the vmt parameter }
          reference_reset_symbol(href2,objectlibrary.newasmsymboldata(excepttype.vmt_mangledname),0);
          reference_reset_symbol(href2,objectlibrary.newasmsymboldata(excepttype.vmt_mangledname),0);
          paraloc1:=paramanager.getintparaloc(pocall_default,1);
          paraloc1:=paramanager.getintparaloc(pocall_default,1);
-         paramanager.allocparaloc(exprasmlist,paraloc1);
-         cg.a_paramaddr_ref(exprasmlist,href2,paraloc1);
+         cg.a_paramaddr_ref(exprasmlist,href2,paraloc1,false);
          paramanager.freeparaloc(exprasmlist,paraloc1);
          paramanager.freeparaloc(exprasmlist,paraloc1);
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_CATCHES');
          cg.a_call_name(exprasmlist,'FPC_CATCHES');
@@ -1245,8 +1236,7 @@ implementation
          cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
          cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          paraloc1:=paramanager.getintparaloc(pocall_default,1);
          paraloc1:=paramanager.getintparaloc(pocall_default,1);
-         paramanager.allocparaloc(exprasmlist,paraloc1);
-         cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
+         cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1,false);
          paramanager.freeparaloc(exprasmlist,paraloc1);
          paramanager.freeparaloc(exprasmlist,paraloc1);
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
@@ -1479,7 +1469,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.85  2003-10-17 14:38:32  peter
+  Revision 1.86  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.85  2003/10/17 14:38:32  peter
     * 64k registers supported
     * 64k registers supported
     * fixed some memory leaks
     * fixed some memory leaks
 
 

+ 10 - 9
compiler/ncginl.pas

@@ -188,24 +188,20 @@ implementation
        maketojumpbool(exprasmlist,tcallparanode(left).left,lr_load_regvars);
        maketojumpbool(exprasmlist,tcallparanode(left).left,lr_load_regvars);
        cg.a_label(exprasmlist,falselabel);
        cg.a_label(exprasmlist,falselabel);
        { erroraddr }
        { erroraddr }
-       paramanager.allocparaloc(exprasmlist,paraloc4);
-       cg.a_param_reg(exprasmlist,OS_ADDR,NR_FRAME_POINTER_REG,paraloc4);
+       cg.a_param_reg(exprasmlist,OS_ADDR,NR_FRAME_POINTER_REG,paraloc4,false);
        { lineno }
        { lineno }
-       paramanager.allocparaloc(exprasmlist,paraloc3);
-       cg.a_param_const(exprasmlist,OS_INT,aktfilepos.line,paraloc3);
+       cg.a_param_const(exprasmlist,OS_INT,aktfilepos.line,paraloc3,false);
        { filename string }
        { filename string }
        hp2:=cstringconstnode.createstr(current_module.sourcefiles.get_file_name(aktfilepos.fileindex),st_shortstring);
        hp2:=cstringconstnode.createstr(current_module.sourcefiles.get_file_name(aktfilepos.fileindex),st_shortstring);
        firstpass(tnode(hp2));
        firstpass(tnode(hp2));
        secondpass(tnode(hp2));
        secondpass(tnode(hp2));
        if codegenerror then
        if codegenerror then
           exit;
           exit;
-       paramanager.allocparaloc(exprasmlist,paraloc2);
-       cg.a_paramaddr_ref(exprasmlist,hp2.location.reference,paraloc2);
+       cg.a_paramaddr_ref(exprasmlist,hp2.location.reference,paraloc2,false);
        hp2.free;
        hp2.free;
        { push msg }
        { push msg }
        secondpass(tcallparanode(tcallparanode(left).right).left);
        secondpass(tcallparanode(tcallparanode(left).right).left);
-       paramanager.allocparaloc(exprasmlist,paraloc1);
-       cg.a_paramaddr_ref(exprasmlist,tcallparanode(tcallparanode(left).right).left.location.reference,paraloc1);
+       cg.a_paramaddr_ref(exprasmlist,tcallparanode(tcallparanode(left).right).left.location.reference,paraloc1,false);
        { call }
        { call }
        paramanager.freeparaloc(exprasmlist,paraloc1);
        paramanager.freeparaloc(exprasmlist,paraloc1);
        paramanager.freeparaloc(exprasmlist,paraloc2);
        paramanager.freeparaloc(exprasmlist,paraloc2);
@@ -656,7 +652,12 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.47  2003-10-10 17:48:13  peter
+  Revision 1.48  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.47  2003/10/10 17:48:13  peter
     * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
     * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
     * tregisteralloctor renamed to trgobj
     * tregisteralloctor renamed to trgobj
     * removed rgobj from a lot of units
     * removed rgobj from a lot of units

+ 7 - 3
compiler/ncgld.pas

@@ -154,8 +154,7 @@ implementation
                        cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,hregister,norelocatelab);
                        cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,hregister,norelocatelab);
                        { don't save the allocated register else the result will be destroyed later }
                        { don't save the allocated register else the result will be destroyed later }
                        reference_reset_symbol(href,objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname),0);
                        reference_reset_symbol(href,objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname),0);
-                       paramanager.allocparaloc(exprasmlist,paraloc1);
-                       cg.a_param_ref(exprasmlist,OS_ADDR,href,paraloc1);
+                       cg.a_param_ref(exprasmlist,OS_ADDR,href,paraloc1,false);
                        paramanager.freeparaloc(exprasmlist,paraloc1);
                        paramanager.freeparaloc(exprasmlist,paraloc1);
                        cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                        cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                        cg.a_call_reg(exprasmlist,hregister);
                        cg.a_call_reg(exprasmlist,hregister);
@@ -892,7 +891,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.100  2003-12-01 18:44:15  peter
+  Revision 1.101  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.100  2003/12/01 18:44:15  peter
     * fixed some crashes
     * fixed some crashes
     * fixed varargs and register calling probs
     * fixed varargs and register calling probs
 
 

+ 7 - 3
compiler/ncgmat.pas

@@ -331,8 +331,7 @@ implementation
                   objectlibrary.getlabel(hl);
                   objectlibrary.getlabel(hl);
                   cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_NE,0,hdenom,hl);
                   cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_NE,0,hdenom,hl);
                   paraloc1:=paramanager.getintparaloc(pocall_default,1);
                   paraloc1:=paramanager.getintparaloc(pocall_default,1);
-                  paramanager.allocparaloc(exprasmlist,paraloc1);
-                  cg.a_param_const(exprasmlist,OS_S32,200,paraloc1);
+                  cg.a_param_const(exprasmlist,OS_S32,200,paraloc1,false);
                   paramanager.freeparaloc(exprasmlist,paraloc1);
                   paramanager.freeparaloc(exprasmlist,paraloc1);
                   cg.a_call_name(exprasmlist,'FPC_HANDLERROR');
                   cg.a_call_name(exprasmlist,'FPC_HANDLERROR');
                   cg.a_label(exprasmlist,hl);
                   cg.a_label(exprasmlist,hl);
@@ -502,7 +501,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.21  2003-10-10 17:48:13  peter
+  Revision 1.22  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.21  2003/10/10 17:48:13  peter
     * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
     * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
     * tregisteralloctor renamed to trgobj
     * tregisteralloctor renamed to trgobj
     * removed rgobj from a lot of units
     * removed rgobj from a lot of units

+ 16 - 21
compiler/ncgmem.pas

@@ -292,8 +292,7 @@ implementation
             (not tpointerdef(left.resulttype.def).is_far) then
             (not tpointerdef(left.resulttype.def).is_far) then
           begin
           begin
             paraloc1:=paramanager.getintparaloc(pocall_default,1);
             paraloc1:=paramanager.getintparaloc(pocall_default,1);
-            paramanager.allocparaloc(exprasmlist,paraloc1);
-            cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
+            cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1,false);
             paramanager.freeparaloc(exprasmlist,paraloc1);
             paramanager.freeparaloc(exprasmlist,paraloc1);
             { FPC_CHECKPOINTER uses saveregisters }
             { FPC_CHECKPOINTER uses saveregisters }
             cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
             cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
@@ -346,8 +345,7 @@ implementation
                 not(cs_compilesystem in aktmoduleswitches) then
                 not(cs_compilesystem in aktmoduleswitches) then
               begin
               begin
                 paraloc1:=paramanager.getintparaloc(pocall_default,1);
                 paraloc1:=paramanager.getintparaloc(pocall_default,1);
-                paramanager.allocparaloc(exprasmlist,paraloc1);
-                cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
+                cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1,false);
                 paramanager.freeparaloc(exprasmlist,paraloc1);
                 paramanager.freeparaloc(exprasmlist,paraloc1);
                 { FPC_CHECKPOINTER uses saveregisters }
                 { FPC_CHECKPOINTER uses saveregisters }
                 cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
                 cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
@@ -363,8 +361,7 @@ implementation
                 not(cs_compilesystem in aktmoduleswitches) then
                 not(cs_compilesystem in aktmoduleswitches) then
               begin
               begin
                 paraloc1:=paramanager.getintparaloc(pocall_default,1);
                 paraloc1:=paramanager.getintparaloc(pocall_default,1);
-                paramanager.allocparaloc(exprasmlist,paraloc1);
-                cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
+                cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1,false);
                 paramanager.freeparaloc(exprasmlist,paraloc1);
                 paramanager.freeparaloc(exprasmlist,paraloc1);
                 { FPC_CHECKPOINTER uses saveregisters }
                 { FPC_CHECKPOINTER uses saveregisters }
                 cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
                 cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
@@ -557,10 +554,8 @@ implementation
             begin
             begin
                paraloc1:=paramanager.getintparaloc(pocall_default,1);
                paraloc1:=paramanager.getintparaloc(pocall_default,1);
                paraloc2:=paramanager.getintparaloc(pocall_default,2);
                paraloc2:=paramanager.getintparaloc(pocall_default,2);
-               paramanager.allocparaloc(exprasmlist,paraloc2);
-               cg.a_param_loc(exprasmlist,right.location,paraloc2);
-               paramanager.allocparaloc(exprasmlist,paraloc1);
-               cg.a_param_loc(exprasmlist,left.location,paraloc1);
+               cg.a_param_loc(exprasmlist,right.location,paraloc2,false);
+               cg.a_param_loc(exprasmlist,left.location,paraloc1,false);
                paramanager.freeparaloc(exprasmlist,paraloc1);
                paramanager.freeparaloc(exprasmlist,paraloc1);
                paramanager.freeparaloc(exprasmlist,paraloc2);
                paramanager.freeparaloc(exprasmlist,paraloc2);
                cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -620,8 +615,7 @@ implementation
               if (cs_check_range in aktlocalswitches) then
               if (cs_check_range in aktlocalswitches) then
                 begin
                 begin
                    paraloc1:=paramanager.getintparaloc(pocall_default,1);
                    paraloc1:=paramanager.getintparaloc(pocall_default,1);
-                   paramanager.allocparaloc(exprasmlist,paraloc1);
-                   cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,paraloc1);
+                   cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,paraloc1,false);
                    paramanager.freeparaloc(exprasmlist,paraloc1);
                    paramanager.freeparaloc(exprasmlist,paraloc1);
                    cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                    cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                    cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_CHECKZERO');
                    cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_CHECKZERO');
@@ -700,12 +694,10 @@ implementation
                            begin
                            begin
                               paraloc1:=paramanager.getintparaloc(pocall_default,1);
                               paraloc1:=paramanager.getintparaloc(pocall_default,1);
                               paraloc2:=paramanager.getintparaloc(pocall_default,2);
                               paraloc2:=paramanager.getintparaloc(pocall_default,2);
-                              paramanager.allocparaloc(exprasmlist,paraloc2);
-                              cg.a_param_const(exprasmlist,OS_INT,tordconstnode(right).value,paraloc2);
+                              cg.a_param_const(exprasmlist,OS_INT,tordconstnode(right).value,paraloc2,false);
                               href:=location.reference;
                               href:=location.reference;
                               dec(href.offset,7);
                               dec(href.offset,7);
-                              paramanager.allocparaloc(exprasmlist,paraloc1);
-                              cg.a_param_ref(exprasmlist,OS_INT,href,paraloc1);
+                              cg.a_param_ref(exprasmlist,OS_INT,href,paraloc1,false);
                               paramanager.freeparaloc(exprasmlist,paraloc1);
                               paramanager.freeparaloc(exprasmlist,paraloc1);
                               paramanager.freeparaloc(exprasmlist,paraloc2);
                               paramanager.freeparaloc(exprasmlist,paraloc2);
                               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -834,12 +826,10 @@ implementation
                            begin
                            begin
                               paraloc1:=paramanager.getintparaloc(pocall_default,1);
                               paraloc1:=paramanager.getintparaloc(pocall_default,1);
                               paraloc2:=paramanager.getintparaloc(pocall_default,2);
                               paraloc2:=paramanager.getintparaloc(pocall_default,2);
-                              paramanager.allocparaloc(exprasmlist,paraloc2);
-                              cg.a_param_reg(exprasmlist,OS_INT,right.location.register,paraloc2);
+                              cg.a_param_reg(exprasmlist,OS_INT,right.location.register,paraloc2,false);
                               href:=location.reference;
                               href:=location.reference;
                               dec(href.offset,7);
                               dec(href.offset,7);
-                              paramanager.allocparaloc(exprasmlist,paraloc1);
-                              cg.a_param_ref(exprasmlist,OS_INT,href,paraloc1);
+                              cg.a_param_ref(exprasmlist,OS_INT,href,paraloc1,false);
                               paramanager.freeparaloc(exprasmlist,paraloc1);
                               paramanager.freeparaloc(exprasmlist,paraloc1);
                               paramanager.freeparaloc(exprasmlist,paraloc2);
                               paramanager.freeparaloc(exprasmlist,paraloc2);
                               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -878,7 +868,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.81  2003-11-23 17:03:35  peter
+  Revision 1.82  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.81  2003/11/23 17:03:35  peter
     * fixed parentfp loading, it was using the offset of the current
     * fixed parentfp loading, it was using the offset of the current
       nested proc instead of the parent
       nested proc instead of the parent
 
 

+ 31 - 13
compiler/ncgutil.pas

@@ -278,13 +278,10 @@ implementation
         paraloc1:=paramanager.getintparaloc(pocall_default,1);
         paraloc1:=paramanager.getintparaloc(pocall_default,1);
         paraloc2:=paramanager.getintparaloc(pocall_default,2);
         paraloc2:=paramanager.getintparaloc(pocall_default,2);
         paraloc3:=paramanager.getintparaloc(pocall_default,3);
         paraloc3:=paramanager.getintparaloc(pocall_default,3);
-        paramanager.allocparaloc(list,paraloc3);
-        cg.a_paramaddr_ref(list,envbuf,paraloc3);
-        paramanager.allocparaloc(list,paraloc2);
-        cg.a_paramaddr_ref(list,jmpbuf,paraloc2);
+        cg.a_paramaddr_ref(list,envbuf,paraloc3,false);
+        cg.a_paramaddr_ref(list,jmpbuf,paraloc2,false);
         { push type of exceptionframe }
         { push type of exceptionframe }
-        paramanager.allocparaloc(list,paraloc1);
-        cg.a_param_const(list,OS_S32,1,paraloc1);
+        cg.a_param_const(list,OS_S32,1,paraloc1,false);
         paramanager.freeparaloc(list,paraloc3);
         paramanager.freeparaloc(list,paraloc3);
         paramanager.freeparaloc(list,paraloc2);
         paramanager.freeparaloc(list,paraloc2);
         paramanager.freeparaloc(list,paraloc1);
         paramanager.freeparaloc(list,paraloc1);
@@ -293,8 +290,7 @@ implementation
         cg.deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         cg.deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
 
 
         paraloc1:=paramanager.getintparaloc(pocall_default,1);
         paraloc1:=paramanager.getintparaloc(pocall_default,1);
-        paramanager.allocparaloc(list,paraloc1);
-        cg.a_param_reg(list,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1);
+        cg.a_param_reg(list,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1,false);
         paramanager.freeparaloc(list,paraloc1);
         paramanager.freeparaloc(list,paraloc1);
         cg.allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         cg.allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         cg.a_call_name(list,'FPC_SETJMP');
         cg.a_call_name(list,'FPC_SETJMP');
@@ -1286,11 +1282,9 @@ implementation
               reference_reset_symbol(href,objectlibrary.newasmsymboldata('etext'),0);
               reference_reset_symbol(href,objectlibrary.newasmsymboldata('etext'),0);
               paraloc1:=paramanager.getintparaloc(pocall_default,1);
               paraloc1:=paramanager.getintparaloc(pocall_default,1);
               paraloc2:=paramanager.getintparaloc(pocall_default,2);
               paraloc2:=paramanager.getintparaloc(pocall_default,2);
-              paramanager.allocparaloc(list,paraloc2);
-              cg.a_paramaddr_ref(list,href,paraloc2);
+              cg.a_paramaddr_ref(list,href,paraloc2,false);
               reference_reset_symbol(href,objectlibrary.newasmsymboldata('__image_base__'),0);
               reference_reset_symbol(href,objectlibrary.newasmsymboldata('__image_base__'),0);
-              paramanager.allocparaloc(list,paraloc1);
-              cg.a_paramaddr_ref(list,href,paraloc1);
+              cg.a_paramaddr_ref(list,href,paraloc1,false);
               paramanager.freeparaloc(list,paraloc2);
               paramanager.freeparaloc(list,paraloc2);
               paramanager.freeparaloc(list,paraloc1);
               paramanager.freeparaloc(list,paraloc1);
               cg.allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_cdecl));
               cg.allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_cdecl));
@@ -1452,11 +1446,30 @@ implementation
 
 
     procedure gen_stackalloc_code(list:Taasmoutput);
     procedure gen_stackalloc_code(list:Taasmoutput);
       var
       var
+        hitemp,
+        lotemp,
         stackframe : longint;
         stackframe : longint;
       begin
       begin
         { Calculate size of stackframe }
         { Calculate size of stackframe }
         stackframe:=current_procinfo.calc_stackframe_size;
         stackframe:=current_procinfo.calc_stackframe_size;
 
 
+        { All temps are know, write offsets used for information }
+        if (cs_asm_source in aktglobalswitches) then
+          begin
+            if tg.direction>0 then
+              begin
+                lotemp:=current_procinfo.tempstart;
+                hitemp:=tg.lasttemp;
+              end
+            else
+              begin
+                lotemp:=tg.lasttemp;
+                hitemp:=current_procinfo.tempstart;
+              end;
+            list.concat(Tai_comment.Create(strpnew('Temps allocated between '+std_regname(current_procinfo.framepointer)+
+              tostr_with_plus(lotemp)+' and '+std_regname(current_procinfo.framepointer)+tostr_with_plus(hitemp))));
+          end;
+
 {$ifndef powerpc}
 {$ifndef powerpc}
         { at least for the ppc this applies always, so this code isn't usable (FK) }
         { at least for the ppc this applies always, so this code isn't usable (FK) }
         { omit stack frame ? }
         { omit stack frame ? }
@@ -1982,7 +1995,12 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.171  2003-11-30 19:35:29  florian
+  Revision 1.172  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.171  2003/11/30 19:35:29  florian
     * fixed several arm related problems
     * fixed several arm related problems
 
 
   Revision 1.170  2003/11/29 20:13:25  florian
   Revision 1.170  2003/11/29 20:13:25  florian

+ 40 - 31
compiler/paramgr.pas

@@ -83,6 +83,7 @@ unit paramgr;
             @param(loc Parameter location)
             @param(loc Parameter location)
           }
           }
           procedure allocparaloc(list: taasmoutput; const loc: tparalocation); virtual;
           procedure allocparaloc(list: taasmoutput; const loc: tparalocation); virtual;
+          procedure alloctempparaloc(list: taasmoutput;var locpara:tparalocation);virtual;
 
 
           {# free a parameter location allocated with allocparaloc
           {# free a parameter location allocated with allocparaloc
 
 
@@ -112,7 +113,6 @@ unit paramgr;
           { Return the location of the low and high part of a 64bit parameter }
           { Return the location of the low and high part of a 64bit parameter }
           procedure splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);virtual;
           procedure splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);virtual;
 
 
-          procedure alloctempregs(list: taasmoutput;var locpara:tparalocation);virtual;
        end;
        end;
 
 
 
 
@@ -320,6 +320,39 @@ implementation
       end;
       end;
 
 
 
 
+    procedure tparamanager.alloctempparaloc(list: taasmoutput;var locpara:tparalocation);
+      begin
+        case locpara.loc of
+          LOC_REFERENCE:
+            begin
+              { no temp needed by default }
+            end;
+          LOC_REGISTER:
+            begin
+{$ifndef cpu64bit}
+              if locpara.size in [OS_64,OS_S64] then
+                begin
+                  locpara.registerlow:=cg.getintregister(list,OS_32);
+                  locpara.registerhigh:=cg.getintregister(list,OS_32);
+                end
+              else
+{$endif cpu64bit}
+                locpara.register:=cg.getintregister(list,locpara.size);
+            end;
+          LOC_FPUREGISTER:
+            begin
+              locpara.register:=cg.getfpuregister(list,locpara.size);
+            end;
+          LOC_MMREGISTER:
+            begin
+              locpara.register:=cg.getfpuregister(list,locpara.size);
+            end;
+          else
+            internalerror(200308123);
+        end;
+      end;
+
+
     procedure tparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
     procedure tparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
       begin
       begin
         case loc.loc of
         case loc.loc of
@@ -375,35 +408,6 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tparamanager.alloctempregs(list: taasmoutput;var locpara:tparalocation);
-      begin
-        case locpara.loc of
-          LOC_REGISTER:
-            begin
-{$ifndef cpu64bit}
-              if locpara.size in [OS_64,OS_S64] then
-                begin
-                  locpara.registerlow:=cg.getintregister(list,OS_32);
-                  locpara.registerhigh:=cg.getintregister(list,OS_32);
-                end
-              else
-{$endif cpu64bit}
-                locpara.register:=cg.getintregister(list,locpara.size);
-            end;
-          LOC_FPUREGISTER:
-            begin
-              locpara.register:=cg.getfpuregister(list,locpara.size);
-            end;
-          LOC_MMREGISTER:
-            begin
-              locpara.register:=cg.getfpuregister(list,locpara.size);
-            end;
-          else
-            internalerror(200308123);
-        end;
-      end;
-
-
     function tparamanager.create_inline_paraloc_info(p : tabstractprocdef):longint;
     function tparamanager.create_inline_paraloc_info(p : tabstractprocdef):longint;
       var
       var
         hp : tparaitem;
         hp : tparaitem;
@@ -450,7 +454,12 @@ end.
 
 
 {
 {
    $Log$
    $Log$
-   Revision 1.65  2003-10-29 21:24:14  jonas
+   Revision 1.66  2003-12-03 23:13:20  peter
+     * delayed paraloc allocation, a_param_*() gets extra parameter
+       if it needs to allocate temp or real paralocation
+     * optimized/simplified int-real loading
+
+   Revision 1.65  2003/10/29 21:24:14  jonas
      + support for fpu temp parameters
      + support for fpu temp parameters
      + saving/restoring of fpu register before/after a procedure call
      + saving/restoring of fpu register before/after a procedure call
 
 

+ 9 - 1
compiler/procinfo.pas

@@ -78,6 +78,9 @@ unit procinfo;
           { Size of the parameters on the stack }
           { Size of the parameters on the stack }
           para_stack_size : longint;
           para_stack_size : longint;
 
 
+          { Offset of temp after para/local are allocated }
+          tempstart : longint;
+
           {# some collected informations about the procedure
           {# some collected informations about the procedure
              see pi_xxxx constants above
              see pi_xxxx constants above
           }
           }
@@ -208,7 +211,12 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.8  2003-11-10 22:02:52  peter
+  Revision 1.9  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.8  2003/11/10 22:02:52  peter
     * cross unit inlining fixed
     * cross unit inlining fixed
 
 
   Revision 1.7  2003/10/17 14:38:32  peter
   Revision 1.7  2003/10/17 14:38:32  peter

+ 25 - 20
compiler/psub.pas

@@ -529,9 +529,9 @@ implementation
           depending on the implicit finally we need to add
           depending on the implicit finally we need to add
           an try...finally...end wrapper }
           an try...finally...end wrapper }
         newblock:=internalstatements(newstatement);
         newblock:=internalstatements(newstatement);
-        if (pi_needs_implicit_finally in current_procinfo.flags) and
+        if (pi_needs_implicit_finally in flags) and
            { but it's useless in init/final code of units }
            { but it's useless in init/final code of units }
-           not(current_procinfo.procdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
+           not(procdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
           begin
           begin
             { Generate special exception block only needed when
             { Generate special exception block only needed when
               implicit finaly is used }
               implicit finaly is used }
@@ -642,17 +642,17 @@ implementation
             { Create register allocator }
             { Create register allocator }
             cg.init_register_allocators;
             cg.init_register_allocators;
 
 
-            current_procinfo.set_first_temp_offset;
-            current_procinfo.generate_parameter_info;
+            set_first_temp_offset;
+            generate_parameter_info;
 
 
             { Allocate space in temp/registers for parast and localst }
             { Allocate space in temp/registers for parast and localst }
             aktfilepos:=entrypos;
             aktfilepos:=entrypos;
-            gen_alloc_parast(aktproccode,tparasymtable(current_procinfo.procdef.parast));
-            if current_procinfo.procdef.localst.symtabletype=localsymtable then
-              gen_alloc_localst(aktproccode,tlocalsymtable(current_procinfo.procdef.localst));
-            if (cs_asm_source in aktglobalswitches) then
-              aktproccode.concat(Tai_comment.Create(strpnew('Temps start at '+std_regname(current_procinfo.framepointer)+
-                  tostr_with_plus(tg.lasttemp))));
+            gen_alloc_parast(aktproccode,tparasymtable(procdef.parast));
+            if procdef.localst.symtabletype=localsymtable then
+              gen_alloc_localst(aktproccode,tlocalsymtable(procdef.localst));
+
+            { Store temp offset for information about 'real' temps }
+            tempstart:=tg.lasttemp;
 
 
             { Generate code to load register parameters in temps and insert local
             { Generate code to load register parameters in temps and insert local
               copies for values parameters. This must be done before the code for the
               copies for values parameters. This must be done before the code for the
@@ -672,7 +672,7 @@ implementation
 
 
             { generate code for the node tree }
             { generate code for the node tree }
             do_secondpass(code);
             do_secondpass(code);
-            current_procinfo.aktproccode.concatlist(exprasmlist);
+            aktproccode.concatlist(exprasmlist);
 {$ifdef i386}
 {$ifdef i386}
             procdef.fpu_used:=code.registersfpu;
             procdef.fpu_used:=code.registersfpu;
 {$endif i386}
 {$endif i386}
@@ -702,7 +702,7 @@ implementation
             else
             else
               aktproccode.concatlist(templist);
               aktproccode.concatlist(templist);
             { insert exit label at the correct position }
             { insert exit label at the correct position }
-            cg.a_label(templist,current_procinfo.aktexitlabel);
+            cg.a_label(templist,aktexitlabel);
             if assigned(exitlabel_asmnode.currenttai) then
             if assigned(exitlabel_asmnode.currenttai) then
               aktproccode.insertlistafter(exitlabel_asmnode.currenttai,templist)
               aktproccode.insertlistafter(exitlabel_asmnode.currenttai,templist)
             else
             else
@@ -743,9 +743,9 @@ implementation
             { Free space in temp/registers for parast and localst, must be
             { Free space in temp/registers for parast and localst, must be
               done after gen_entry_code }
               done after gen_entry_code }
             aktfilepos:=exitpos;
             aktfilepos:=exitpos;
-            if current_procinfo.procdef.localst.symtabletype=localsymtable then
-              gen_free_localst(aktproccode,tlocalsymtable(current_procinfo.procdef.localst));
-            gen_free_parast(aktproccode,tparasymtable(current_procinfo.procdef.parast));
+            if procdef.localst.symtabletype=localsymtable then
+              gen_free_localst(aktproccode,tlocalsymtable(procdef.localst));
+            gen_free_parast(aktproccode,tparasymtable(procdef.parast));
 
 
             { The procedure body is finished, we can now
             { The procedure body is finished, we can now
               allocate the registers }
               allocate the registers }
@@ -773,9 +773,9 @@ implementation
             if not(cs_no_regalloc in aktglobalswitches) then
             if not(cs_no_regalloc in aktglobalswitches) then
               begin
               begin
                 if (cs_optimize in aktglobalswitches) and
                 if (cs_optimize in aktglobalswitches) and
-                { do not optimize pure assembler procedures }
-                    not(pi_is_assembler in current_procinfo.flags)  then
-                    optimize(aktproccode);
+                   { do not optimize pure assembler procedures }
+                   not(pi_is_assembler in flags)  then
+                  optimize(aktproccode);
               end;
               end;
 {$endif NoOpt}
 {$endif NoOpt}
 
 
@@ -1004,7 +1004,7 @@ implementation
     {$endif state_tracking}
     {$endif state_tracking}
 
 
          { reset to normal non static function }
          { reset to normal non static function }
-         if (current_procinfo.procdef.parast.symtablelevel=normal_function_level) then
+         if (procdef.parast.symtablelevel=normal_function_level) then
            allow_only_static:=false;
            allow_only_static:=false;
          current_procinfo:=oldprocinfo;
          current_procinfo:=oldprocinfo;
 
 
@@ -1318,7 +1318,12 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.174  2003-11-27 09:08:01  florian
+  Revision 1.175  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.174  2003/11/27 09:08:01  florian
     * resourcestring is allowed in the interface
     * resourcestring is allowed in the interface
 
 
   Revision 1.173  2003/11/23 17:05:16  peter
   Revision 1.173  2003/11/23 17:05:16  peter

+ 20 - 13
compiler/x86/cgx86.pas

@@ -62,10 +62,10 @@ unit cgx86;
         { left to right), this allows to move the parameter to    }
         { left to right), this allows to move the parameter to    }
         { register, if the cpu supports register calling          }
         { register, if the cpu supports register calling          }
         { conventions                                             }
         { conventions                                             }
-        procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);override;
-        procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);override;
-        procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);override;
-        procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);override;
+        procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;var locpara : tparalocation;alloctemp:boolean);override;
+        procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;var locpara : tparalocation;alloctemp:boolean);override;
+        procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;var locpara : tparalocation;alloctemp:boolean);override;
+        procedure a_paramaddr_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);override;
 
 
         procedure a_call_name(list : taasmoutput;const s : string);override;
         procedure a_call_name(list : taasmoutput;const s : string);override;
         procedure a_call_reg(list : taasmoutput;reg : tregister);override;
         procedure a_call_reg(list : taasmoutput;reg : tregister);override;
@@ -282,6 +282,8 @@ unit cgx86;
             result:=rgint.uses_registers;
             result:=rgint.uses_registers;
           R_SSEREGISTER :
           R_SSEREGISTER :
             result:=rgmm.uses_registers;
             result:=rgmm.uses_registers;
+          R_FPUREGISTER :
+            result:=false;
           else
           else
             internalerror(200310094);
             internalerror(200310094);
         end;
         end;
@@ -486,7 +488,7 @@ unit cgx86;
     { we implement the following routines because otherwise we can't }
     { we implement the following routines because otherwise we can't }
     { instantiate the class since it's abstract                      }
     { instantiate the class since it's abstract                      }
 
 
-    procedure tcgx86.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);
+    procedure tcgx86.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;var locpara : tparalocation;alloctemp:boolean);
       begin
       begin
         check_register_size(size,r);
         check_register_size(size,r);
         if (locpara.loc=LOC_REFERENCE) and
         if (locpara.loc=LOC_REFERENCE) and
@@ -512,11 +514,11 @@ unit cgx86;
             end;
             end;
           end
           end
         else
         else
-          inherited a_param_reg(list,size,r,locpara);
+          inherited a_param_reg(list,size,r,locpara,alloctemp);
       end;
       end;
 
 
 
 
-    procedure tcgx86.a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);
+    procedure tcgx86.a_param_const(list : taasmoutput;size : tcgsize;a : aword;var locpara : tparalocation;alloctemp:boolean);
 
 
       begin
       begin
         if (locpara.loc=LOC_REFERENCE) and
         if (locpara.loc=LOC_REFERENCE) and
@@ -537,11 +539,11 @@ unit cgx86;
             end;
             end;
           end
           end
         else
         else
-          inherited a_param_const(list,size,a,locpara);
+          inherited a_param_const(list,size,a,locpara,alloctemp);
       end;
       end;
 
 
 
 
-    procedure tcgx86.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);
+    procedure tcgx86.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;var locpara : tparalocation;alloctemp:boolean);
 
 
       var
       var
         pushsize : tcgsize;
         pushsize : tcgsize;
@@ -575,11 +577,11 @@ unit cgx86;
             end;
             end;
           end
           end
         else
         else
-          inherited a_param_ref(list,size,r,locpara);
+          inherited a_param_ref(list,size,r,locpara,alloctemp);
       end;
       end;
 
 
 
 
-    procedure tcgx86.a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
+    procedure tcgx86.a_paramaddr_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);
       var
       var
         tmpreg : tregister;
         tmpreg : tregister;
       begin
       begin
@@ -610,7 +612,7 @@ unit cgx86;
               end;
               end;
           end
           end
         else
         else
-          inherited a_paramaddr_ref(list,r,locpara);
+          inherited a_paramaddr_ref(list,r,locpara,alloctemp);
       end;
       end;
 
 
 
 
@@ -1749,7 +1751,12 @@ unit cgx86;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.87  2003-11-05 23:06:03  florian
+  Revision 1.88  2003-12-03 23:13:20  peter
+    * delayed paraloc allocation, a_param_*() gets extra parameter
+      if it needs to allocate temp or real paralocation
+    * optimized/simplified int-real loading
+
+  Revision 1.87  2003/11/05 23:06:03  florian
     * elesize of g_copyvaluepara_openarray changed
     * elesize of g_copyvaluepara_openarray changed
 
 
   Revision 1.86  2003/10/30 18:53:53  marco
   Revision 1.86  2003/10/30 18:53:53  marco