mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 14:39:36 +01:00 
			
		
		
		
	* push_addr_param must be defined per target
This commit is contained in:
		
							parent
							
								
									c55c88db32
								
							
						
					
					
						commit
						18ebd28692
					
				@ -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
 | 
			
		||||
 | 
			
		||||
@ -84,7 +84,10 @@ unit cpupara;
 | 
			
		||||
        while assigned(paraloc) do
 | 
			
		||||
          begin
 | 
			
		||||
            if (paraloc^.loc<>LOC_REFERENCE) then
 | 
			
		||||
              begin
 | 
			
		||||
                result:=false;
 | 
			
		||||
                exit;
 | 
			
		||||
              end;
 | 
			
		||||
            paraloc:=paraloc^.next;
 | 
			
		||||
          end;
 | 
			
		||||
      end;
 | 
			
		||||
@ -116,39 +119,64 @@ 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
 | 
			
		||||
              { Win32 passes small records on the stack for call by
 | 
			
		||||
                value }
 | 
			
		||||
                    if (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
 | 
			
		||||
              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
 | 
			
		||||
                     begin
 | 
			
		||||
                       result:=false;
 | 
			
		||||
                       exit;
 | 
			
		||||
                     end;
 | 
			
		||||
                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 (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
 | 
			
		||||
              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:=false;
 | 
			
		||||
                       exit;
 | 
			
		||||
                  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;
 | 
			
		||||
        end;
 | 
			
		||||
        result:=inherited push_addr_param(varspez,def,calloption);
 | 
			
		||||
      end;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    function ti386paramanager.get_para_align(calloption : tproccalloption):byte;
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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!!!)
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user