Difference between revisions of "FPC Internals/Parameters"

From Free Pascal wiki
Jump to navigationJump to search
m
m
 
(14 intermediate revisions by one other user not shown)
Line 1: Line 1:
 +
{{FPC_Internals/Parameters}}
 +
 +
back to contents [[FPC internals]]
 +
 
FPC is using the CPU target specified parameter manager to manage the location of parameters passed into and routines.
 
FPC is using the CPU target specified parameter manager to manage the location of parameters passed into and routines.
  
Line 9: Line 13:
 
The basic TParaManager class cannot and should not be created, as it contain the abstract methods that should be implemented by CPU target implementation class.
 
The basic TParaManager class cannot and should not be created, as it contain the abstract methods that should be implemented by CPU target implementation class.
  
==Methods to Implement===
+
==Methods to Implement==
 
The following methods are critical for CPU target implementation
 
The following methods are critical for CPU target implementation
 
===push_addr_param===
 
===push_addr_param===
Returns true if a parameter is too large to copy and only the address is pushed.
+
Returns true if a parameter is too large to copy and only the address is pushed or if the parameter should be passed by address reference at all time.
  function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;virtual;abstract;
+
<source lang="delphi">
 +
  function push_addr_param(varspez: tvarspez; def: tdef; calloption: tproccalloption) : boolean;
 +
</source>
 +
The typical approach would be first to inspect variable specifier argument '''varspez'''.
 +
 
 +
Normally, vs_var, vs_out, vs_constref are always passed by reference and '''push_addr_param''' should return true.
 +
 
 +
In many cases '''var_const''' should return true as well, however, it's driven by CPU target ABI and calling convention. (for example, if definition ('''def''') is a record and it can fit CPU word, then the value of the structure can be put into memory/register. Thus the function should return false)
 +
 
 +
If there variable specifier doesn't indicate a need to pass by address, the next step is to inspect a definition.
 +
 
 +
The following definition types ('''def.typ''') are typically passed via address (and the function should return true for those):
 +
* Formal (formaldef)
 +
* Object instances (objectdef, but only if is_object() returns true)
 +
* Strings (stringdef) for types st_shortstring or st_longstring.
 +
* Arrays (arraydef) for open arrays, arrays of const.
 +
 
 +
Depending on CPU type '''calloption''' should be considered, if different calling conventions apply for the CPU target.
 +
 
 
===create_paraloc_info===
 
===create_paraloc_info===
 
This is used to populate the location information on all parameters
 
This is used to populate the location information on all parameters
 
for the routine as seen in either the caller or the callee. It returns
 
for the routine as seen in either the caller or the callee. It returns
 
the size allocated on the stack
 
the size allocated on the stack
  function  create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;virtual;abstract;
+
<source lang="delphi">
 +
  function  create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
 +
</source>
 +
 
 
===create_varargs_paraloc_info===
 
===create_varargs_paraloc_info===
 
This is used to populate the location information on all parameters
 
This is used to populate the location information on all parameters
 
for the routine that are passed as varargs. It returns
 
for the routine that are passed as varargs. It returns
 
the size allocated on the stack (including the normal parameters)
 
the size allocated on the stack (including the normal parameters)
  function  create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;virtual;abstract;
+
<source lang="delphi">
 +
  function  create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;
 +
</source>
 +
 
 
===get_funcretloc===
 
===get_funcretloc===
 
Returns the location of the function result if p had def as
 
Returns the location of the function result if p had def as
Line 29: Line 57:
 
forces the function result to something different than the real
 
forces the function result to something different than the real
 
result.   
 
result.   
  function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;virtual;abstract;
+
<source lang="delphi">
 
+
  function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
 
+
</source>
  
 
==See Also==
 
==See Also==
 
*[[FPC Internals]]
 
*[[FPC Internals]]
  
[[Category:FPC internals]]
+
<!--[[Category:FPC internals]]-->

Latest revision as of 12:15, 28 December 2020

English (en)

back to contents FPC internals

FPC is using the CPU target specified parameter manager to manage the location of parameters passed into and routines.


CPU target should implement parameter manager in cpupara.pas unit.

The unit should initialize the global ParaManager variable if an instance of the CPU specific class.

ParaManager:=tcpuparamanager.create

The basic TParaManager class cannot and should not be created, as it contain the abstract methods that should be implemented by CPU target implementation class.

Methods to Implement

The following methods are critical for CPU target implementation

push_addr_param

Returns true if a parameter is too large to copy and only the address is pushed or if the parameter should be passed by address reference at all time.

 function push_addr_param(varspez: tvarspez; def: tdef; calloption: tproccalloption) : boolean;

The typical approach would be first to inspect variable specifier argument varspez.

Normally, vs_var, vs_out, vs_constref are always passed by reference and push_addr_param should return true.

In many cases var_const should return true as well, however, it's driven by CPU target ABI and calling convention. (for example, if definition (def) is a record and it can fit CPU word, then the value of the structure can be put into memory/register. Thus the function should return false)

If there variable specifier doesn't indicate a need to pass by address, the next step is to inspect a definition.

The following definition types (def.typ) are typically passed via address (and the function should return true for those):

  • Formal (formaldef)
  • Object instances (objectdef, but only if is_object() returns true)
  • Strings (stringdef) for types st_shortstring or st_longstring.
  • Arrays (arraydef) for open arrays, arrays of const.

Depending on CPU type calloption should be considered, if different calling conventions apply for the CPU target.

create_paraloc_info

This is used to populate the location information on all parameters for the routine as seen in either the caller or the callee. It returns the size allocated on the stack

 function  create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;

create_varargs_paraloc_info

This is used to populate the location information on all parameters for the routine that are passed as varargs. It returns the size allocated on the stack (including the normal parameters)

 function  create_varargs_paraloc_info(p : tabstractprocdef; side: tcallercallee; varargspara:tvarargsparalist):longint;

get_funcretloc

Returns the location of the function result if p had def as function result instead of its actual result. Used if the compiler forces the function result to something different than the real result.

 function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;

See Also