Browse Source

* push_addr_param must be defined per target

peter 20 years ago
parent
commit
18ebd28692

+ 9 - 3
compiler/arm/cpupara.pas

@@ -159,12 +159,15 @@ unit cpupara;
 
     function tarmparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
       begin
+        result:=false;
         if varspez in [vs_var,vs_out] then
           begin
             result:=true;
             exit;
           end;
         case def.deftype of
+          variantdef,
+          formaldef,
           recorddef:
             result:=true;
           arraydef:
@@ -172,14 +175,14 @@ unit cpupara;
                              is_open_array(def) or
                              is_array_of_const(def) or
                              is_array_constructor(def);
+          objectdef :
+            result:=is_object(def);
           setdef :
             result:=(tsetdef(def).settype<>smallset);
           stringdef :
             result:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
           procvardef :
             result:=po_methodpointer in tprocvardef(def).procoptions;
-          else
-            result:=inherited push_addr_param(varspez,def,calloption);
         end;
       end;
 
@@ -446,7 +449,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.29  2005-01-15 21:45:35  florian
+  Revision 1.30  2005-02-03 20:04:49  peter
+    * push_addr_param must be defined per target
+
+  Revision 1.29  2005/01/15 21:45:35  florian
     * arm compiler fixed
 
   Revision 1.28  2005/01/01 19:30:17  florian

+ 62 - 31
compiler/i386/cpupara.pas

@@ -84,7 +84,10 @@ unit cpupara;
         while assigned(paraloc) do
           begin
             if (paraloc^.loc<>LOC_REFERENCE) then
-              result:=false;
+              begin
+                result:=false;
+                exit;
+              end;
             paraloc:=paraloc^.next;
           end;
       end;
@@ -116,38 +119,63 @@ unit cpupara;
 
     function ti386paramanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
       begin
-        case target_info.system of
-          system_i386_win32 :
+        result:=false;
+        { var,out always require address }
+        if varspez in [vs_var,vs_out] then
+          begin
+            result:=true;
+            exit;
+          end;
+        { Only vs_const, vs_value here }
+        case def.deftype of
+          variantdef,
+          formaldef :
+            result:=true;
+          recorddef :
             begin
-              case def.deftype of
-                recorddef :
-                  begin
-                    { Win32 passes small records on the stack for call by
-                      value }
-                    if (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
-                       (varspez=vs_value) and
-                       (def.size<=8) then
-                     begin
-                       result:=false;
-                       exit;
-                     end;
-                  end;
-                arraydef :
-                  begin
-                    { Win32 passes arrays on the stack for call by
-                      value }
-                    if (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
-                       (varspez=vs_value) and
-                       (tarraydef(def).highrange>=tarraydef(def).lowrange) then
-                     begin
-                       result:=false;
-                       exit;
-                     end;
-                  end;
-              end;
+              { Win32 passes small records on the stack for call by
+                value }
+              if (target_info.system=system_i386_win32) and
+                 (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
+                 (varspez=vs_value) and
+                 (def.size<=8) then
+                result:=false
+              else
+                result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (def.size>sizeof(aint));
             end;
+          arraydef :
+            begin
+              { Win32 passes arrays on the stack for call by
+                value }
+              if (target_info.system=system_i386_win32) and
+                 (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
+                 (varspez=vs_value) and
+                 (tarraydef(def).highrange>=tarraydef(def).lowrange) then
+                result:=false
+              else
+              { array of const values are pushed on the stack }
+                if (calloption in [pocall_cdecl,pocall_cppdecl]) then
+                  result:=not is_array_of_const(def)
+              else
+                begin
+                  result:=(
+                           (tarraydef(def).highrange>=tarraydef(def).lowrange) and
+                           (def.size>sizeof(aint))
+                          ) or
+                          is_open_array(def) or
+                          is_array_of_const(def) or
+                          is_array_constructor(def);
+                end;
+            end;
+          objectdef :
+            result:=is_object(def);
+          stringdef :
+            result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tstringdef(def).string_typ in [st_shortstring,st_longstring]);
+          procvardef :
+            result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (po_methodpointer in tprocvardef(def).procoptions);
+          setdef :
+            result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tsetdef(def).settype<>smallset);
         end;
-        result:=inherited push_addr_param(varspez,def,calloption);
       end;
 
 
@@ -602,7 +630,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.64  2005-01-30 11:03:22  peter
+  Revision 1.65  2005-02-03 20:04:49  peter
+    * push_addr_param must be defined per target
+
+  Revision 1.64  2005/01/30 11:03:22  peter
     * revert last commit
 
   Revision 1.62  2005/01/18 22:19:20  peter

+ 5 - 49
compiler/paramgr.pas

@@ -52,7 +52,7 @@ unit paramgr;
           { Returns true if a parameter is too large to copy and only
             the address is pushed
           }
-          function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;virtual;
+          function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;virtual;abstract;
           { return the size of a push }
           function push_size(varspez:tvarspez;def : tdef;calloption : tproccalloption) : longint;
           {# Returns a structure giving the information on
@@ -157,53 +157,6 @@ implementation
       end;
 
 
-    { true if a parameter is too large to copy and only the address is pushed }
-    function tparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
-      begin
-        result:=false;
-        { var,out always require address }
-        if varspez in [vs_var,vs_out] then
-          begin
-            result:=true;
-            exit;
-          end;
-        { Only vs_const, vs_value here }
-        case def.deftype of
-          variantdef,
-          formaldef :
-            result:=true;
-          recorddef :
-            result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (def.size>sizeof(aint));
-          arraydef :
-            begin
-              if (calloption in [pocall_cdecl,pocall_cppdecl]) then
-               begin
-                 { array of const values are pushed on the stack }
-                 result:=not is_array_of_const(def);
-               end
-              else
-               begin
-                 result:=(
-                          (tarraydef(def).highrange>=tarraydef(def).lowrange) and
-                          (def.size>sizeof(aint))
-                         ) or
-                         is_open_array(def) or
-                         is_array_of_const(def) or
-                         is_array_constructor(def);
-               end;
-            end;
-          objectdef :
-            result:=is_object(def);
-          stringdef :
-            result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tstringdef(def).string_typ in [st_shortstring,st_longstring]);
-          procvardef :
-            result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (po_methodpointer in tprocvardef(def).procoptions);
-          setdef :
-            result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tsetdef(def).settype<>smallset);
-        end;
-      end;
-
-
     { return the size of a push }
     function tparamanager.push_size(varspez:tvarspez;def : tdef;calloption : tproccalloption) : longint;
       begin
@@ -433,7 +386,10 @@ end.
 
 {
    $Log$
-   Revision 1.85  2005-01-20 17:47:01  peter
+   Revision 1.86  2005-02-03 20:04:49  peter
+     * push_addr_param must be defined per target
+
+   Revision 1.85  2005/01/20 17:47:01  peter
      * remove copy_value_on_stack and a_param_copy_ref
 
    Revision 1.84  2005/01/18 22:19:20  peter

+ 10 - 3
compiler/powerpc/cpupara.pas

@@ -173,6 +173,7 @@ unit cpupara;
 
     function tppcparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
       begin
+        result:=false;
         { var,out always require address }
         if varspez in [vs_var,vs_out] then
           begin
@@ -180,6 +181,9 @@ unit cpupara;
             exit;
           end;
         case def.deftype of
+          variantdef,
+          formaldef :
+            result:=true;
           recorddef:
             result :=(target_info.abi<>abi_powerpc_aix);
           arraydef:
@@ -187,14 +191,14 @@ unit cpupara;
                              is_open_array(def) or
                              is_array_of_const(def) or
                              is_array_constructor(def);
+          objectdef :
+            result:=is_object(def);
           setdef :
             result:=(tsetdef(def).settype<>smallset);
           stringdef :
             result:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
           procvardef :
             result:=po_methodpointer in tprocvardef(def).procoptions;
-          else
-            result:=inherited push_addr_param(varspez,def,calloption);
         end;
       end;
 
@@ -645,7 +649,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.86  2005-01-31 17:46:25  peter
+  Revision 1.87  2005-02-03 20:04:49  peter
+    * push_addr_param must be defined per target
+
+  Revision 1.86  2005/01/31 17:46:25  peter
     * fixed parseparaloc
 
   Revision 1.85  2005/01/20 17:47:01  peter

+ 1 - 1
compiler/utils/samplecfg

@@ -162,7 +162,7 @@ cat <<EOFCFG > $thefile
 #-Cr
 #-Ct
 
-# Optimizer switches
+# Optimizer switches for i386 compiler
 # -Og        generate smaller code
 # -OG        generate faster code (default)
 # -Or        keep certain variables in registers (still BUGGY!!!)

+ 67 - 5
compiler/x86_64/cpupara.pas

@@ -40,6 +40,8 @@ unit cpupara;
           procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;paras:tparalist;
                                                var intparareg,mmparareg,parasize:longint);
        public
+          function param_use_paraloc(const cgpara:tcgpara):boolean;override;
+          function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
           procedure getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);override;
           function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
@@ -140,6 +142,66 @@ unit cpupara;
       end;
 
 
+    function tx86_64paramanager.param_use_paraloc(const cgpara:tcgpara):boolean;
+      var
+        paraloc : pcgparalocation;
+      begin
+        if not assigned(cgpara.location) then
+          internalerror(200410102);
+        result:=true;
+        { All locations are LOC_REFERENCE }
+        paraloc:=cgpara.location;
+        while assigned(paraloc) do
+          begin
+            if (paraloc^.loc<>LOC_REFERENCE) then
+              begin
+                result:=false;
+                exit;
+              end;
+            paraloc:=paraloc^.next;
+          end;
+      end;
+
+
+    { true if a parameter is too large to copy and only the address is pushed }
+    function tx86_64paramanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
+      begin
+        result:=false;
+        { var,out always require address }
+        if varspez in [vs_var,vs_out] then
+          begin
+            result:=true;
+            exit;
+          end;
+        { Only vs_const, vs_value here }
+        case def.deftype of
+          variantdef,
+          formaldef :
+            result:=true;
+          recorddef :
+            result:=(def.size>sizeof(aint));
+          arraydef :
+            begin
+              result:=(
+                       (tarraydef(def).highrange>=tarraydef(def).lowrange) and
+                       (def.size>sizeof(aint))
+                      ) or
+                      is_open_array(def) or
+                      is_array_of_const(def) or
+                      is_array_constructor(def);
+            end;
+          objectdef :
+            result:=is_object(def);
+          stringdef :
+            result:=(tstringdef(def).string_typ in [st_shortstring,st_longstring]);
+          procvardef :
+            result:=(po_methodpointer in tprocvardef(def).procoptions);
+          setdef :
+            result:=(tsetdef(def).settype<>smallset);
+        end;
+      end;
+
+
     function tx86_64paramanager.get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;
       begin
         result:=[RS_RAX,RS_RCX,RS_RDX,RS_RSI,RS_RDI,RS_R8,RS_R9,RS_R10,RS_R11];
@@ -350,10 +412,7 @@ unit cpupara;
                             end
                           else
                             begin
-                              if (paralen<=sizeof(aint)) then
-                                l:=paralen
-                              else
-                                l:=sizeof(aint);
+                              l:=paralen;
                               paraloc^.size:=int_cgsize(l);
                             end;
                           if side=callerside then
@@ -433,7 +492,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.15  2005-02-03 18:32:25  peter
+  Revision 1.16  2005-02-03 20:04:49  peter
+    * push_addr_param must be defined per target
+
+  Revision 1.15  2005/02/03 18:32:25  peter
     * fix extended paraloc
 
   Revision 1.14  2005/01/29 11:36:52  peter