瀏覽代碼

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

peter 21 年之前
父節點
當前提交
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_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
            removing superfluous opcodes. Returns TRUE if normal processing
@@ -452,31 +452,43 @@ unit cg64f32;
       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
         tmplochi,tmploclo: tparalocation;
       begin
+        if alloctemp then
+          paramanager.alloctempparaloc(list,locpara)
+        else
+          paramanager.allocparaloc(list,locpara);
         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;
 
 
-    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
         tmplochi,tmploclo: tparalocation;
       begin
+        if alloctemp then
+          paramanager.alloctempparaloc(list,locpara)
+        else
+          paramanager.allocparaloc(list,locpara);
         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;
 
 
-    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
         tmprefhi,tmpreflo : treference;
         tmploclo,tmplochi : tparalocation;
       begin
+        if alloctemp then
+          paramanager.alloctempparaloc(list,locpara)
+        else
+          paramanager.allocparaloc(list,locpara);
         paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
         tmprefhi:=r;
         tmpreflo:=r;
@@ -484,22 +496,22 @@ unit cg64f32;
           inc(tmpreflo.offset,4)
         else
           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;
 
 
-    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
         case l.loc of
           LOC_REGISTER,
           LOC_CREGISTER :
-            a_param64_reg(list,l.register64,locpara);
+            a_param64_reg(list,l.register64,locpara,alloctemp);
           LOC_CONSTANT :
-            a_param64_const(list,l.valueqword,locpara);
+            a_param64_const(list,l.valueqword,locpara,alloctemp);
           LOC_CREFERENCE,
           LOC_REFERENCE :
-            a_param64_ref(list,l.reference,locpara);
+            a_param64_ref(list,l.reference,locpara,alloctemp);
           else
             internalerror(200203287);
         end;
@@ -761,7 +773,12 @@ begin
 end.
 {
   $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
     * tregisteralloctor renamed to trgobj
     * 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(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.
 
              A generic version is provided. This routine should
@@ -128,7 +128,7 @@ unit cgobj;
              @param(a value of constant to send)
              @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.
 
              A generic version is provided. This routine should
@@ -139,7 +139,7 @@ unit cgobj;
              @param(r Memory reference of value to send)
              @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,
              to a routine.
 
@@ -149,7 +149,7 @@ unit cgobj;
              @param(nr parameter number (starting from one) of routine (from left to right))
              @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
              will calculate the address of the reference, and pass this
              calculated address as a parameter.
@@ -161,10 +161,10 @@ unit cgobj;
              @param(r reference to get address from)
              @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 }
-          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:
             * 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
@@ -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_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
@@ -600,10 +600,14 @@ implementation
           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
          ref : treference;
       begin
+         if alloctemp then
+           paramanager.alloctempparaloc(list,locpara)
+         else
+           paramanager.allocparaloc(list,locpara);
          case locpara.loc of
             LOC_REGISTER,LOC_CREGISTER:
               a_load_reg_reg(list,size,locpara.size,r,locpara.register);
@@ -619,8 +623,8 @@ implementation
          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
          hr : tregister;
 
@@ -628,49 +632,50 @@ implementation
          hr:=getintregister(list,size);
          a_load_const_reg(list,size,a,hr);
          ungetregister(list,hr);
-         a_param_reg(list,size,hr,locpara);
+         a_param_reg(list,size,hr,locpara,alloctemp);
       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
          hr : tregister;
       begin
          hr:=getintregister(list,size);
          a_load_ref_reg(list,size,size,r,hr);
          ungetregister(list,hr);
-         a_param_reg(list,size,hr,locpara);
+         a_param_reg(list,size,hr,locpara,alloctemp);
       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
         case l.loc of
           LOC_REGISTER,
           LOC_CREGISTER :
-            a_param_reg(list,l.size,l.register,locpara);
+            a_param_reg(list,l.size,l.register,locpara,alloctemp);
           LOC_CONSTANT :
-            a_param_const(list,l.size,l.value,locpara);
+            a_param_const(list,l.size,l.value,locpara,alloctemp);
           LOC_CREFERENCE,
           LOC_REFERENCE :
-            a_param_ref(list,l.size,l.reference,locpara);
+            a_param_ref(list,l.size,l.reference,locpara,alloctemp);
         else
           internalerror(2002032211);
         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
          hr : tregister;
       begin
          hr:=getaddressregister(list);
          a_loadaddr_ref_reg(list,r,hr);
          ungetregister(list,hr);
-         a_param_reg(list,OS_ADDR,hr,locpara);
+         a_param_reg(list,OS_ADDR,hr,locpara,alloctemp);
       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
         ref : treference;
       begin
@@ -1273,17 +1278,14 @@ implementation
         paraloc1:=paramanager.getintparaloc(pocall_default,1);
         paraloc2:=paramanager.getintparaloc(pocall_default,2);
         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
-          a_param_ref(list,OS_ADDR,source,paraloc2)
+          a_param_ref(list,OS_ADDR,source,paraloc2,false)
         else
-          a_paramaddr_ref(list,source,paraloc2);
+          a_paramaddr_ref(list,source,paraloc2,false);
         if delsource then
          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,paraloc2);
         paramanager.freeparaloc(list,paraloc1);
@@ -1317,8 +1319,7 @@ implementation
          if incrfunc<>'' then
           begin
             { 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);
             allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
             a_call_name(list,incrfunc);
@@ -1327,13 +1328,11 @@ implementation
          else
           begin
             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
-              a_param_ref(list,OS_ADDR,ref,paraloc1)
+              a_param_ref(list,OS_ADDR,ref,paraloc1,false)
             else
-              a_paramaddr_ref(list,ref,paraloc1);
+              a_paramaddr_ref(list,ref,paraloc1,false);
             paramanager.freeparaloc(list,paraloc1);
             paramanager.freeparaloc(list,paraloc2);
             allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -1372,14 +1371,12 @@ implementation
             if needrtti then
              begin
                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;
-            paramanager.allocparaloc(list,paraloc1);
             if loadref then
-              a_param_ref(list,OS_ADDR,ref,paraloc1)
+              a_param_ref(list,OS_ADDR,ref,paraloc1,false)
             else
-              a_paramaddr_ref(list,ref,paraloc1);
+              a_paramaddr_ref(list,ref,paraloc1,false);
             paramanager.freeparaloc(list,paraloc1);
             if needrtti then
               paramanager.freeparaloc(list,paraloc2);
@@ -1390,13 +1387,11 @@ implementation
          else
           begin
             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
-              a_param_ref(list,OS_ADDR,ref,paraloc1)
+              a_param_ref(list,OS_ADDR,ref,paraloc1,false)
             else
-              a_paramaddr_ref(list,ref,paraloc1);
+              a_paramaddr_ref(list,ref,paraloc1,false);
             paramanager.freeparaloc(list,paraloc1);
             paramanager.freeparaloc(list,paraloc2);
             allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -1420,13 +1415,11 @@ implementation
          else
            begin
               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
-                a_param_ref(list,OS_ADDR,ref,paraloc1)
+                a_param_ref(list,OS_ADDR,ref,paraloc1,false)
               else
-                a_paramaddr_ref(list,ref,paraloc1);
+                a_paramaddr_ref(list,ref,paraloc1,false);
               paramanager.freeparaloc(list,paraloc1);
               paramanager.freeparaloc(list,paraloc2);
               allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -1450,13 +1443,11 @@ implementation
          else
            begin
               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
-                a_param_ref(list,OS_ADDR,ref,paraloc1)
+                a_param_ref(list,OS_ADDR,ref,paraloc1,false)
               else
-                a_paramaddr_ref(list,ref,paraloc1);
+                a_paramaddr_ref(list,ref,paraloc1,false);
               paramanager.freeparaloc(list,paraloc1);
               paramanager.freeparaloc(list,paraloc2);
               allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -1581,8 +1572,7 @@ implementation
         paraloc1 : tparalocation;
       begin
          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);
          { No register saving needed, saveregisters is used }
          a_call_name(list,'FPC_STACKCHECK');
@@ -1612,8 +1602,7 @@ implementation
            objectlibrary.getlabel(oklabel);
            a_cmp_const_reg_label(list,OS_ADDR,OC_NE,0,reg,oklabel);
            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);
            a_call_name(list,'FPC_HANDLEERROR');
            a_label(list,oklabel);
@@ -1631,10 +1620,8 @@ implementation
         if (cs_check_object in aktlocalswitches) then
          begin
            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,paraloc2);
            { No register saving needed, saveregisters is used }
@@ -1643,8 +1630,7 @@ implementation
         else
          if (cs_check_range in aktlocalswitches) then
           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);
             { No register saving needed, saveregisters is used }
             a_call_name(list,'FPC_CHECK_OBJECT');
@@ -1817,7 +1803,12 @@ finalization
 end.
 {
   $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
     + g_releaesvaluepara_openarray added
 

+ 7 - 13
compiler/i386/cpupara.pas

@@ -129,16 +129,6 @@ unit cpupara;
               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);
       end;
 
@@ -419,7 +409,6 @@ unit cpupara;
             if (parareg<=high(parasupregs)) and
                not(
                    is_64bit or
-                   (hp.paratype.def.deftype=floatdef) or
                    ((hp.paratype.def.deftype in [floatdef,recorddef,arraydef]) and
                     (not pushaddr))
                   ) then
@@ -462,7 +451,7 @@ unit cpupara;
                 hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
                 if side=calleeside then
                   inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
-              end;    
+              end;
             hp:=tparaitem(hp.next);
           end;
         { We need to return the size allocated }
@@ -498,7 +487,12 @@ begin
 end.
 {
   $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 varargs and register calling probs
 

+ 10 - 9
compiler/i386/n386add.pas

@@ -356,8 +356,7 @@ interface
                          end
                        else
                          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;
                        secondpass(right);
                        location_release(exprasmlist,right.location);
@@ -368,21 +367,18 @@ interface
                          end
                        else
                          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;
                        { push parameters }
                        if paraloc1.loc=LOC_REGISTER then
                          begin
                            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;
                        if paraloc2.loc=LOC_REGISTER then
                          begin
                            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;
                        paramanager.freeparaloc(exprasmlist,paraloc1);
                        paramanager.freeparaloc(exprasmlist,paraloc2);
@@ -1495,7 +1491,12 @@ begin
 end.
 {
   $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
     * fixed some memory leaks
 

+ 32 - 79
compiler/i386/n386cnv.pas

@@ -65,8 +65,8 @@ implementation
       symconst,symdef,aasmbase,aasmtai,aasmcpu,
       cgbase,
       ncon,ncal,ncnv,
-      cpubase,
-      cgobj,cga,cgx86;
+      cpubase,tgobj,
+      cgobj,cga,cgx86,ncgutil;
 
 
     function ti386typeconvnode.first_int_to_real : tnode;
@@ -85,92 +85,45 @@ implementation
          href : treference;
          hregister : tregister;
          l1,l2 : tasmlabel;
-         freereg : boolean;
-
       begin
          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
-           u32bit:
-             begin
-                emit_ref(A_FILD,S_IQ,href);
-                emit_const_reg(A_ADD,S_L,8,NR_ESP);
-             end;
+           u32bit,
            scurrency,
            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:
              begin
                 { unsigned 64 bit ints are harder to handle: }
                 { we load bits 0..62 and then check bit 63:  }
                 { if it is 1 then we add $80000000 000000000 }
                 { as double                                  }
-                inc(href.offset,4);
+                inc(left.location.reference.offset,4);
                 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);
                 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.getlabel(l2);
                 cg.a_jmp_flags(exprasmlist,F_E,l2);
@@ -181,16 +134,11 @@ implementation
                 reference_reset_symbol(href,l1,0);
                 emit_ref(A_FADD,S_FL,href);
                 cg.a_label(exprasmlist,l2);
-                emit_const_reg(A_ADD,S_L,8,NR_ESP);
              end
            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;
+         location_freetemp(exprasmlist,left.location);
          tcgx86(cg).inc_fpu_stack;
          location.register:=NR_ST;
       end;
@@ -236,7 +184,12 @@ begin
 end.
 {
   $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
     * cnv. node second pass uses now as well helper wrappers
 

+ 33 - 31
compiler/ncgcal.pas

@@ -35,7 +35,6 @@ interface
        tcgcallparanode = class(tcallparanode)
        private
           tempparaloc : tparalocation;
-          procedure allocate_tempparaloc;
           procedure push_addr_para;
           procedure push_value_para;
        public
@@ -99,22 +98,12 @@ implementation
                              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;
       begin
         if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
           internalerror(200304235);
         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);
       end;
 
@@ -137,7 +126,6 @@ implementation
         if left.resulttype.def.deftype=floatdef then
          begin
            location_release(exprasmlist,left.location);
-           allocate_tempparaloc;
 {$ifdef i386}
            if tempparaloc.loc<>LOC_REFERENCE then
              internalerror(200309291);
@@ -180,7 +168,7 @@ implementation
                            dec(href.offset,2);
                            dec(size,2);
                          end;
-                        cg.a_param_ref(exprasmlist,cgsize,href,tempparaloc);
+                        cg.a_param_ref(exprasmlist,cgsize,href,tempparaloc,true);
                       end;
                    end
                  else
@@ -215,7 +203,6 @@ implementation
                   aktcallnode.procdefinition.proccalloption) then
             begin
               location_release(exprasmlist,left.location);
-              allocate_tempparaloc;
 {$ifdef i386}
               if tempparaloc.loc<>LOC_REFERENCE then
                 internalerror(200309292);
@@ -249,16 +236,14 @@ implementation
                     if cgsize in [OS_64,OS_S64] then
                      begin
                        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);
                      end
                     else
                      begin
                        location_release(exprasmlist,left.location);
-                       allocate_tempparaloc;
                        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;
 {$ifdef SUPPORT_MMX}
@@ -266,7 +251,6 @@ implementation
                 LOC_CMMXREGISTER:
                   begin
                      location_release(exprasmlist,left.location);
-                     allocate_tempparaloc;
                      inc(tcgcallnode(aktcallnode).pushedparasize,8);
                      cg.a_parammm_reg(exprasmlist,left.location.register);
                   end;
@@ -291,6 +275,12 @@ implementation
                 (nf_varargs_para in flags)) then
            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
            a parameter }
          if (left.nodetype<>nothingn) then
@@ -337,8 +327,7 @@ implementation
                     begin
                       inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
                       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
                   else
                     push_addr_para;
@@ -762,8 +751,10 @@ implementation
                    cg.ungetregister(exprasmlist,pvreg);
 
                    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 }
                    cg.a_call_reg(exprasmlist,pvreg);
@@ -779,8 +770,10 @@ implementation
                   freeparas;
 
                   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
                     extra code }
@@ -815,8 +808,10 @@ implementation
               cg.ungetregister(exprasmlist,pvreg);
 
               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
                 extra code }
@@ -872,8 +867,10 @@ implementation
                  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);
 
          { handle function results }
@@ -1119,7 +1116,12 @@ begin
 end.
 {
   $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
 
   Revision 1.141  2003/11/23 17:39:33  peter

+ 18 - 23
compiler/ncgflw.pas

@@ -825,18 +825,16 @@ implementation
               { Push parameters }
               if assigned(right) then
                 begin
-                  paramanager.allocparaloc(exprasmlist,paraloc3);
                   if assigned(frametree) then
                     begin
                       location_release(exprasmlist,frametree.location);
-                      cg.a_param_loc(exprasmlist,frametree.location,paraloc3)
+                      cg.a_param_loc(exprasmlist,frametree.location,paraloc3,false)
                     end
                   else
-                    cg.a_param_const(exprasmlist,OS_INT,0,paraloc3);
+                    cg.a_param_const(exprasmlist,OS_INT,0,paraloc3,false);
                   { push address }
                   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
               else
                 begin
@@ -845,18 +843,15 @@ implementation
                    cg.a_label(exprasmlist,a);
                    reference_reset_symbol(href2,a,0);
                    { 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 }
-                   paramanager.allocparaloc(exprasmlist,paraloc2);
                    if target_info.system <> system_powerpc_macos then
-                     cg.a_paramaddr_ref(exprasmlist,href2,paraloc2)
+                     cg.a_paramaddr_ref(exprasmlist,href2,paraloc2,false)
                    else
-                     cg.a_param_const(exprasmlist,OS_INT,0,paraloc2);
+                     cg.a_param_const(exprasmlist,OS_INT,0,paraloc2,false);
                 end;
               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,paraloc2);
               paramanager.freeparaloc(exprasmlist,paraloc3);
@@ -912,8 +907,7 @@ implementation
          cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          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);
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
@@ -1021,8 +1015,7 @@ implementation
                 'default handler' flag (=-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);
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_CATCHES');
@@ -1049,8 +1042,7 @@ implementation
               cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
 
               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);
               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
               cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
@@ -1186,8 +1178,7 @@ implementation
          { send the vmt parameter }
          reference_reset_symbol(href2,objectlibrary.newasmsymboldata(excepttype.vmt_mangledname),0);
          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);
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_CATCHES');
@@ -1245,8 +1236,7 @@ implementation
          cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
          cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          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);
          cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
@@ -1479,7 +1469,12 @@ begin
 end.
 {
   $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
     * fixed some memory leaks
 

+ 10 - 9
compiler/ncginl.pas

@@ -188,24 +188,20 @@ implementation
        maketojumpbool(exprasmlist,tcallparanode(left).left,lr_load_regvars);
        cg.a_label(exprasmlist,falselabel);
        { 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 }
-       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 }
        hp2:=cstringconstnode.createstr(current_module.sourcefiles.get_file_name(aktfilepos.fileindex),st_shortstring);
        firstpass(tnode(hp2));
        secondpass(tnode(hp2));
        if codegenerror then
           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;
        { push msg }
        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 }
        paramanager.freeparaloc(exprasmlist,paraloc1);
        paramanager.freeparaloc(exprasmlist,paraloc2);
@@ -656,7 +652,12 @@ end.
 
 {
   $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
     * tregisteralloctor renamed to trgobj
     * 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);
                        { don't save the allocated register else the result will be destroyed later }
                        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);
                        cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
                        cg.a_call_reg(exprasmlist,hregister);
@@ -892,7 +891,12 @@ begin
 end.
 {
   $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 varargs and register calling probs
 

+ 7 - 3
compiler/ncgmat.pas

@@ -331,8 +331,7 @@ implementation
                   objectlibrary.getlabel(hl);
                   cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_NE,0,hdenom,hl);
                   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);
                   cg.a_call_name(exprasmlist,'FPC_HANDLERROR');
                   cg.a_label(exprasmlist,hl);
@@ -502,7 +501,12 @@ begin
 end.
 {
   $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
     * tregisteralloctor renamed to trgobj
     * 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
           begin
             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);
             { FPC_CHECKPOINTER uses saveregisters }
             cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
@@ -346,8 +345,7 @@ implementation
                 not(cs_compilesystem in aktmoduleswitches) then
               begin
                 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);
                 { FPC_CHECKPOINTER uses saveregisters }
                 cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
@@ -363,8 +361,7 @@ implementation
                 not(cs_compilesystem in aktmoduleswitches) then
               begin
                 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);
                 { FPC_CHECKPOINTER uses saveregisters }
                 cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
@@ -557,10 +554,8 @@ implementation
             begin
                paraloc1:=paramanager.getintparaloc(pocall_default,1);
                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,paraloc2);
                cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -620,8 +615,7 @@ implementation
               if (cs_check_range in aktlocalswitches) then
                 begin
                    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);
                    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');
@@ -700,12 +694,10 @@ implementation
                            begin
                               paraloc1:=paramanager.getintparaloc(pocall_default,1);
                               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;
                               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,paraloc2);
                               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -834,12 +826,10 @@ implementation
                            begin
                               paraloc1:=paramanager.getintparaloc(pocall_default,1);
                               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;
                               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,paraloc2);
                               cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@@ -878,7 +868,12 @@ begin
 end.
 {
   $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
       nested proc instead of the parent
 

+ 31 - 13
compiler/ncgutil.pas

@@ -278,13 +278,10 @@ implementation
         paraloc1:=paramanager.getintparaloc(pocall_default,1);
         paraloc2:=paramanager.getintparaloc(pocall_default,2);
         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 }
-        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,paraloc2);
         paramanager.freeparaloc(list,paraloc1);
@@ -293,8 +290,7 @@ implementation
         cg.deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
 
         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);
         cg.allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
         cg.a_call_name(list,'FPC_SETJMP');
@@ -1286,11 +1282,9 @@ implementation
               reference_reset_symbol(href,objectlibrary.newasmsymboldata('etext'),0);
               paraloc1:=paramanager.getintparaloc(pocall_default,1);
               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);
-              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,paraloc1);
               cg.allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_cdecl));
@@ -1452,11 +1446,30 @@ implementation
 
     procedure gen_stackalloc_code(list:Taasmoutput);
       var
+        hitemp,
+        lotemp,
         stackframe : longint;
       begin
         { Calculate size of stackframe }
         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}
         { at least for the ppc this applies always, so this code isn't usable (FK) }
         { omit stack frame ? }
@@ -1982,7 +1995,12 @@ implementation
 end.
 {
   $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
 
   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)
           }
           procedure allocparaloc(list: taasmoutput; const loc: tparalocation); virtual;
+          procedure alloctempparaloc(list: taasmoutput;var locpara:tparalocation);virtual;
 
           {# 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 }
           procedure splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);virtual;
 
-          procedure alloctempregs(list: taasmoutput;var locpara:tparalocation);virtual;
        end;
 
 
@@ -320,6 +320,39 @@ implementation
       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);
       begin
         case loc.loc of
@@ -375,35 +408,6 @@ implementation
       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;
       var
         hp : tparaitem;
@@ -450,7 +454,12 @@ end.
 
 {
    $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
      + 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 }
           para_stack_size : longint;
 
+          { Offset of temp after para/local are allocated }
+          tempstart : longint;
+
           {# some collected informations about the procedure
              see pi_xxxx constants above
           }
@@ -208,7 +211,12 @@ implementation
 end.
 {
   $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
 
   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
           an try...finally...end wrapper }
         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 }
-           not(current_procinfo.procdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
+           not(procdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
           begin
             { Generate special exception block only needed when
               implicit finaly is used }
@@ -642,17 +642,17 @@ implementation
             { Create register allocator }
             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 }
             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
               copies for values parameters. This must be done before the code for the
@@ -672,7 +672,7 @@ implementation
 
             { generate code for the node tree }
             do_secondpass(code);
-            current_procinfo.aktproccode.concatlist(exprasmlist);
+            aktproccode.concatlist(exprasmlist);
 {$ifdef i386}
             procdef.fpu_used:=code.registersfpu;
 {$endif i386}
@@ -702,7 +702,7 @@ implementation
             else
               aktproccode.concatlist(templist);
             { 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
               aktproccode.insertlistafter(exitlabel_asmnode.currenttai,templist)
             else
@@ -743,9 +743,9 @@ implementation
             { Free space in temp/registers for parast and localst, must be
               done after gen_entry_code }
             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
               allocate the registers }
@@ -773,9 +773,9 @@ implementation
             if not(cs_no_regalloc in aktglobalswitches) then
               begin
                 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;
 {$endif NoOpt}
 
@@ -1004,7 +1004,7 @@ implementation
     {$endif state_tracking}
 
          { 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;
          current_procinfo:=oldprocinfo;
 
@@ -1318,7 +1318,12 @@ implementation
 end.
 {
   $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
 
   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    }
         { register, if the cpu supports register calling          }
         { 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_reg(list : taasmoutput;reg : tregister);override;
@@ -282,6 +282,8 @@ unit cgx86;
             result:=rgint.uses_registers;
           R_SSEREGISTER :
             result:=rgmm.uses_registers;
+          R_FPUREGISTER :
+            result:=false;
           else
             internalerror(200310094);
         end;
@@ -486,7 +488,7 @@ unit cgx86;
     { we implement the following routines because otherwise we can't }
     { 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
         check_register_size(size,r);
         if (locpara.loc=LOC_REFERENCE) and
@@ -512,11 +514,11 @@ unit cgx86;
             end;
           end
         else
-          inherited a_param_reg(list,size,r,locpara);
+          inherited a_param_reg(list,size,r,locpara,alloctemp);
       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
         if (locpara.loc=LOC_REFERENCE) and
@@ -537,11 +539,11 @@ unit cgx86;
             end;
           end
         else
-          inherited a_param_const(list,size,a,locpara);
+          inherited a_param_const(list,size,a,locpara,alloctemp);
       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
         pushsize : tcgsize;
@@ -575,11 +577,11 @@ unit cgx86;
             end;
           end
         else
-          inherited a_param_ref(list,size,r,locpara);
+          inherited a_param_ref(list,size,r,locpara,alloctemp);
       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
         tmpreg : tregister;
       begin
@@ -610,7 +612,7 @@ unit cgx86;
               end;
           end
         else
-          inherited a_paramaddr_ref(list,r,locpara);
+          inherited a_paramaddr_ref(list,r,locpara,alloctemp);
       end;
 
 
@@ -1749,7 +1751,12 @@ unit cgx86;
 end.
 {
   $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
 
   Revision 1.86  2003/10/30 18:53:53  marco