gccint: Register Arguments

1 
1 18.9.7 Passing Arguments in Registers
1 -------------------------------------
1 
1 This section describes the macros which let you control how various
1 types of arguments are passed in registers or how they are arranged in
1 the stack.
1 
1  -- Target Hook: rtx TARGET_FUNCTION_ARG (cumulative_args_t CA,
1           machine_mode MODE, const_tree TYPE, bool NAMED)
1      Return an RTX indicating whether a function argument is passed in a
1      register and if so, which register.
1 
1      The arguments are CA, which summarizes all the previous arguments;
1      MODE, the machine mode of the argument; TYPE, the data type of the
1      argument as a tree node or 0 if that is not known (which happens
1      for C support library functions); and NAMED, which is 'true' for an
1      ordinary argument and 'false' for nameless arguments that
1      correspond to '...' in the called function's prototype.  TYPE can
1      be an incomplete type if a syntax error has previously occurred.
1 
1      The return value is usually either a 'reg' RTX for the hard
1      register in which to pass the argument, or zero to pass the
1      argument on the stack.
1 
1      The return value can be a 'const_int' which means argument is
1      passed in a target specific slot with specified number.  Target
1      hooks should be used to store or load argument in such case.  See
1      'TARGET_STORE_BOUNDS_FOR_ARG' and 'TARGET_LOAD_BOUNDS_FOR_ARG' for
1      more information.
1 
1      The value of the expression can also be a 'parallel' RTX.  This is
1      used when an argument is passed in multiple locations.  The mode of
1      the 'parallel' should be the mode of the entire argument.  The
1      'parallel' holds any number of 'expr_list' pairs; each one
1      describes where part of the argument is passed.  In each
1      'expr_list' the first operand must be a 'reg' RTX for the hard
1      register in which to pass this part of the argument, and the mode
1      of the register RTX indicates how large this part of the argument
1      is.  The second operand of the 'expr_list' is a 'const_int' which
1      gives the offset in bytes into the entire argument of where this
1      part starts.  As a special exception the first 'expr_list' in the
1      'parallel' RTX may have a first operand of zero.  This indicates
1      that the entire argument is also stored on the stack.
1 
1      The last time this hook is called, it is called with 'MODE ==
1      VOIDmode', and its result is passed to the 'call' or 'call_value'
1      pattern as operands 2 and 3 respectively.
1 
1      The usual way to make the ISO library 'stdarg.h' work on a machine
1      where some arguments are usually passed in registers, is to cause
1      nameless arguments to be passed on the stack instead.  This is done
1      by making 'TARGET_FUNCTION_ARG' return 0 whenever NAMED is 'false'.
1 
1      You may use the hook 'targetm.calls.must_pass_in_stack' in the
1      definition of this macro to determine if this argument is of a type
1      that must be passed in the stack.  If 'REG_PARM_STACK_SPACE' is not
1      defined and 'TARGET_FUNCTION_ARG' returns nonzero for such an
1      argument, the compiler will abort.  If 'REG_PARM_STACK_SPACE' is
1      defined, the argument will be computed in the stack and then loaded
1      into a register.
1 
1  -- Target Hook: bool TARGET_MUST_PASS_IN_STACK (machine_mode MODE,
1           const_tree TYPE)
1      This target hook should return 'true' if we should not pass TYPE
1      solely in registers.  The file 'expr.h' defines a definition that
1      is usually appropriate, refer to 'expr.h' for additional
1      documentation.
1 
1  -- Target Hook: rtx TARGET_FUNCTION_INCOMING_ARG (cumulative_args_t CA,
1           machine_mode MODE, const_tree TYPE, bool NAMED)
1      Define this hook if the caller and callee on the target have
1      different views of where arguments are passed.  Also define this
1      hook if there are functions that are never directly called, but are
1      invoked by the hardware and which have nonstandard calling
1      conventions.
1 
1      In this case 'TARGET_FUNCTION_ARG' computes the register in which
1      the caller passes the value, and 'TARGET_FUNCTION_INCOMING_ARG'
1      should be defined in a similar fashion to tell the function being
1      called where the arguments will arrive.
1 
1      'TARGET_FUNCTION_INCOMING_ARG' can also return arbitrary address
1      computation using hard register, which can be forced into a
1      register, so that it can be used to pass special arguments.
1 
1      If 'TARGET_FUNCTION_INCOMING_ARG' is not defined,
1      'TARGET_FUNCTION_ARG' serves both purposes.
1 
1  -- Target Hook: bool TARGET_USE_PSEUDO_PIC_REG (void)
1      This hook should return 1 in case pseudo register should be created
1      for pic_offset_table_rtx during function expand.
1 
1  -- Target Hook: void TARGET_INIT_PIC_REG (void)
1      Perform a target dependent initialization of pic_offset_table_rtx.
1      This hook is called at the start of register allocation.
1 
1  -- Target Hook: int TARGET_ARG_PARTIAL_BYTES (cumulative_args_t CUM,
1           machine_mode MODE, tree TYPE, bool NAMED)
1      This target hook returns the number of bytes at the beginning of an
1      argument that must be put in registers.  The value must be zero for
1      arguments that are passed entirely in registers or that are
1      entirely pushed on the stack.
1 
1      On some machines, certain arguments must be passed partially in
1      registers and partially in memory.  On these machines, typically
1      the first few words of arguments are passed in registers, and the
1      rest on the stack.  If a multi-word argument (a 'double' or a
1      structure) crosses that boundary, its first few words must be
1      passed in registers and the rest must be pushed.  This macro tells
1      the compiler when this occurs, and how many bytes should go in
1      registers.
1 
1      'TARGET_FUNCTION_ARG' for these arguments should return the first
1      register to be used by the caller for this argument; likewise
1      'TARGET_FUNCTION_INCOMING_ARG', for the called function.
1 
1  -- Target Hook: bool TARGET_PASS_BY_REFERENCE (cumulative_args_t CUM,
1           machine_mode MODE, const_tree TYPE, bool NAMED)
1      This target hook should return 'true' if an argument at the
1      position indicated by CUM should be passed by reference.  This
1      predicate is queried after target independent reasons for being
1      passed by reference, such as 'TREE_ADDRESSABLE (type)'.
1 
1      If the hook returns true, a copy of that argument is made in memory
1      and a pointer to the argument is passed instead of the argument
1      itself.  The pointer is passed in whatever way is appropriate for
1      passing a pointer to that type.
1 
1  -- Target Hook: bool TARGET_CALLEE_COPIES (cumulative_args_t CUM,
1           machine_mode MODE, const_tree TYPE, bool NAMED)
1      The function argument described by the parameters to this hook is
1      known to be passed by reference.  The hook should return true if
1      the function argument should be copied by the callee instead of
1      copied by the caller.
1 
1      For any argument for which the hook returns true, if it can be
1      determined that the argument is not modified, then a copy need not
1      be generated.
1 
1      The default version of this hook always returns false.
1 
1  -- Macro: CUMULATIVE_ARGS
1      A C type for declaring a variable that is used as the first
1      argument of 'TARGET_FUNCTION_ARG' and other related values.  For
1      some target machines, the type 'int' suffices and can hold the
1      number of bytes of argument so far.
1 
1      There is no need to record in 'CUMULATIVE_ARGS' anything about the
1      arguments that have been passed on the stack.  The compiler has
1      other variables to keep track of that.  For target machines on
1      which all arguments are passed on the stack, there is no need to
1      store anything in 'CUMULATIVE_ARGS'; however, the data structure
1      must exist and should not be empty, so use 'int'.
1 
1  -- Macro: OVERRIDE_ABI_FORMAT (FNDECL)
1      If defined, this macro is called before generating any code for a
1      function, but after the CFUN descriptor for the function has been
1      created.  The back end may use this macro to update CFUN to reflect
1      an ABI other than that which would normally be used by default.  If
1      the compiler is generating code for a compiler-generated function,
1      FNDECL may be 'NULL'.
1 
1  -- Macro: INIT_CUMULATIVE_ARGS (CUM, FNTYPE, LIBNAME, FNDECL,
1           N_NAMED_ARGS)
1      A C statement (sans semicolon) for initializing the variable CUM
1      for the state at the beginning of the argument list.  The variable
1      has type 'CUMULATIVE_ARGS'.  The value of FNTYPE is the tree node
1      for the data type of the function which will receive the args, or 0
1      if the args are to a compiler support library function.  For direct
1      calls that are not libcalls, FNDECL contain the declaration node of
1      the function.  FNDECL is also set when 'INIT_CUMULATIVE_ARGS' is
1      used to find arguments for the function being compiled.
1      N_NAMED_ARGS is set to the number of named arguments, including a
1      structure return address if it is passed as a parameter, when
1      making a call.  When processing incoming arguments, N_NAMED_ARGS is
1      set to -1.
1 
1      When processing a call to a compiler support library function,
1      LIBNAME identifies which one.  It is a 'symbol_ref' rtx which
1      contains the name of the function, as a string.  LIBNAME is 0 when
1      an ordinary C function call is being processed.  Thus, each time
1      this macro is called, either LIBNAME or FNTYPE is nonzero, but
1      never both of them at once.
1 
1  -- Macro: INIT_CUMULATIVE_LIBCALL_ARGS (CUM, MODE, LIBNAME)
1      Like 'INIT_CUMULATIVE_ARGS' but only used for outgoing libcalls, it
1      gets a 'MODE' argument instead of FNTYPE, that would be 'NULL'.
1      INDIRECT would always be zero, too.  If this macro is not defined,
1      'INIT_CUMULATIVE_ARGS (cum, NULL_RTX, libname, 0)' is used instead.
1 
1  -- Macro: INIT_CUMULATIVE_INCOMING_ARGS (CUM, FNTYPE, LIBNAME)
1      Like 'INIT_CUMULATIVE_ARGS' but overrides it for the purposes of
1      finding the arguments for the function being compiled.  If this
1      macro is undefined, 'INIT_CUMULATIVE_ARGS' is used instead.
1 
1      The value passed for LIBNAME is always 0, since library routines
1      with special calling conventions are never compiled with GCC.  The
1      argument LIBNAME exists for symmetry with 'INIT_CUMULATIVE_ARGS'.
1 
1  -- Target Hook: void TARGET_FUNCTION_ARG_ADVANCE (cumulative_args_t CA,
1           machine_mode MODE, const_tree TYPE, bool NAMED)
1      This hook updates the summarizer variable pointed to by CA to
1      advance past an argument in the argument list.  The values MODE,
1      TYPE and NAMED describe that argument.  Once this is done, the
1      variable CUM is suitable for analyzing the _following_ argument
1      with 'TARGET_FUNCTION_ARG', etc.
1 
1      This hook need not do anything if the argument in question was
1      passed on the stack.  The compiler knows how to track the amount of
1      stack space used for arguments without any special help.
1 
1  -- Target Hook: HOST_WIDE_INT TARGET_FUNCTION_ARG_OFFSET (machine_mode
1           MODE, const_tree TYPE)
1      This hook returns the number of bytes to add to the offset of an
1      argument of type TYPE and mode MODE when passed in memory.  This is
1      needed for the SPU, which passes 'char' and 'short' arguments in
1      the preferred slot that is in the middle of the quad word instead
1      of starting at the top.  The default implementation returns 0.
1 
1  -- Target Hook: pad_direction TARGET_FUNCTION_ARG_PADDING (machine_mode
1           MODE, const_tree TYPE)
1      This hook determines whether, and in which direction, to pad out an
1      argument of mode MODE and type TYPE.  It returns 'PAD_UPWARD' to
1      insert padding above the argument, 'PAD_DOWNWARD' to insert padding
1      below the argument, or 'PAD_NONE' to inhibit padding.
1 
1      The _amount_ of padding is not controlled by this hook, but by
1      'TARGET_FUNCTION_ARG_ROUND_BOUNDARY'.  It is always just enough to
1      reach the next multiple of that boundary.
1 
1      This hook has a default definition that is right for most systems.
1      For little-endian machines, the default is to pad upward.  For
1      big-endian machines, the default is to pad downward for an argument
1      of constant size shorter than an 'int', and upward otherwise.
1 
1  -- Macro: PAD_VARARGS_DOWN
1      If defined, a C expression which determines whether the default
1      implementation of va_arg will attempt to pad down before reading
1      the next argument, if that argument is smaller than its aligned
1      space as controlled by 'PARM_BOUNDARY'.  If this macro is not
1      defined, all such arguments are padded down if 'BYTES_BIG_ENDIAN'
1      is true.
1 
1  -- Macro: BLOCK_REG_PADDING (MODE, TYPE, FIRST)
1      Specify padding for the last element of a block move between
1      registers and memory.  FIRST is nonzero if this is the only
1      element.  Defining this macro allows better control of register
1      function parameters on big-endian machines, without using
1      'PARALLEL' rtl.  In particular, 'MUST_PASS_IN_STACK' need not test
1      padding and mode of types in registers, as there is no longer a
1      "wrong" part of a register; For example, a three byte aggregate may
1      be passed in the high part of a register if so required.
1 
1  -- Target Hook: unsigned int TARGET_FUNCTION_ARG_BOUNDARY (machine_mode
1           MODE, const_tree TYPE)
1      This hook returns the alignment boundary, in bits, of an argument
1      with the specified mode and type.  The default hook returns
1      'PARM_BOUNDARY' for all arguments.
1 
1  -- Target Hook: unsigned int TARGET_FUNCTION_ARG_ROUND_BOUNDARY
1           (machine_mode MODE, const_tree TYPE)
1      Normally, the size of an argument is rounded up to 'PARM_BOUNDARY',
1      which is the default value for this hook.  You can define this hook
1      to return a different value if an argument size must be rounded to
1      a larger value.
1 
1  -- Macro: FUNCTION_ARG_REGNO_P (REGNO)
1      A C expression that is nonzero if REGNO is the number of a hard
1      register in which function arguments are sometimes passed.  This
1      does _not_ include implicit arguments such as the static chain and
1      the structure-value address.  On many machines, no registers can be
1      used for this purpose since all function arguments are pushed on
1      the stack.
1 
1  -- Target Hook: bool TARGET_SPLIT_COMPLEX_ARG (const_tree TYPE)
1      This hook should return true if parameter of type TYPE are passed
1      as two scalar parameters.  By default, GCC will attempt to pack
1      complex arguments into the target's word size.  Some ABIs require
1      complex arguments to be split and treated as their individual
1      components.  For example, on AIX64, complex floats should be passed
1      in a pair of floating point registers, even though a complex float
1      would fit in one 64-bit floating point register.
1 
1      The default value of this hook is 'NULL', which is treated as
1      always false.
1 
1  -- Target Hook: tree TARGET_BUILD_BUILTIN_VA_LIST (void)
1      This hook returns a type node for 'va_list' for the target.  The
1      default version of the hook returns 'void*'.
1 
1  -- Target Hook: int TARGET_ENUM_VA_LIST_P (int IDX, const char **PNAME,
1           tree *PTREE)
1      This target hook is used in function 'c_common_nodes_and_builtins'
1      to iterate through the target specific builtin types for va_list.
1      The variable IDX is used as iterator.  PNAME has to be a pointer to
1      a 'const char *' and PTREE a pointer to a 'tree' typed variable.
1      The arguments PNAME and PTREE are used to store the result of this
1      macro and are set to the name of the va_list builtin type and its
1      internal type.  If the return value of this macro is zero, then
1      there is no more element.  Otherwise the IDX should be increased
1      for the next call of this macro to iterate through all types.
1 
1  -- Target Hook: tree TARGET_FN_ABI_VA_LIST (tree FNDECL)
1      This hook returns the va_list type of the calling convention
1      specified by FNDECL.  The default version of this hook returns
1      'va_list_type_node'.
1 
1  -- Target Hook: tree TARGET_CANONICAL_VA_LIST_TYPE (tree TYPE)
1      This hook returns the va_list type of the calling convention
1      specified by the type of TYPE.  If TYPE is not a valid va_list
1      type, it returns 'NULL_TREE'.
1 
1  -- Target Hook: tree TARGET_GIMPLIFY_VA_ARG_EXPR (tree VALIST, tree
1           TYPE, gimple_seq *PRE_P, gimple_seq *POST_P)
1      This hook performs target-specific gimplification of 'VA_ARG_EXPR'.
1      The first two parameters correspond to the arguments to 'va_arg';
1      the latter two are as in 'gimplify.c:gimplify_expr'.
1 
1  -- Target Hook: bool TARGET_VALID_POINTER_MODE (scalar_int_mode MODE)
1      Define this to return nonzero if the port can handle pointers with
1      machine mode MODE.  The default version of this hook returns true
1      for both 'ptr_mode' and 'Pmode'.
1 
1  -- Target Hook: bool TARGET_REF_MAY_ALIAS_ERRNO (struct ao_ref *REF)
1      Define this to return nonzero if the memory reference REF may alias
1      with the system C library errno location.  The default version of
1      this hook assumes the system C library errno location is either a
1      declaration of type int or accessed by dereferencing a pointer to
1      int.
1 
1  -- Target Hook: bool TARGET_SCALAR_MODE_SUPPORTED_P (scalar_mode MODE)
1      Define this to return nonzero if the port is prepared to handle
1      insns involving scalar mode MODE.  For a scalar mode to be
1      considered supported, all the basic arithmetic and comparisons must
1      work.
1 
1      The default version of this hook returns true for any mode required
1      to handle the basic C types (as defined by the port).  Included
1      here are the double-word arithmetic supported by the code in
1      'optabs.c'.
1 
1  -- Target Hook: bool TARGET_VECTOR_MODE_SUPPORTED_P (machine_mode MODE)
1      Define this to return nonzero if the port is prepared to handle
1      insns involving vector mode MODE.  At the very least, it must have
1      move patterns for this mode.
1 
1  -- Target Hook: opt_machine_mode TARGET_ARRAY_MODE (machine_mode MODE,
1           unsigned HOST_WIDE_INT NELEMS)
1      Return the mode that GCC should use for an array that has NELEMS
1      elements, with each element having mode MODE.  Return no mode if
1      the target has no special requirements.  In the latter case, GCC
1      looks for an integer mode of the appropriate size if available and
1      uses BLKmode otherwise.  Usually the search for the integer mode is
1      limited to 'MAX_FIXED_MODE_SIZE', but the
1      'TARGET_ARRAY_MODE_SUPPORTED_P' hook allows a larger mode to be
1      used in specific cases.
1 
1      The main use of this hook is to specify that an array of vectors
1      should also have a vector mode.  The default implementation returns
1      no mode.
1 
1  -- Target Hook: bool TARGET_ARRAY_MODE_SUPPORTED_P (machine_mode MODE,
1           unsigned HOST_WIDE_INT NELEMS)
1      Return true if GCC should try to use a scalar mode to store an
1      array of NELEMS elements, given that each element has mode MODE.
1      Returning true here overrides the usual 'MAX_FIXED_MODE' limit and
1      allows GCC to use any defined integer mode.
1 
1      One use of this hook is to support vector load and store operations
1      that operate on several homogeneous vectors.  For example, ARM NEON
1      has operations like:
1 
1           int8x8x3_t vld3_s8 (const int8_t *)
1 
1      where the return type is defined as:
1 
1           typedef struct int8x8x3_t
1           {
1             int8x8_t val[3];
1           } int8x8x3_t;
1 
1      If this hook allows 'val' to have a scalar mode, then 'int8x8x3_t'
1      can have the same mode.  GCC can then store 'int8x8x3_t's in
1      registers rather than forcing them onto the stack.
1 
1  -- Target Hook: bool TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
1           (scalar_float_mode MODE)
1      Define this to return nonzero if libgcc provides support for the
1      floating-point mode MODE, which is known to pass
1      'TARGET_SCALAR_MODE_SUPPORTED_P'.  The default version of this hook
1      returns true for all of 'SFmode', 'DFmode', 'XFmode' and 'TFmode',
1      if such modes exist.
1 
1  -- Target Hook: opt_scalar_float_mode TARGET_FLOATN_MODE (int N, bool
1           EXTENDED)
1      Define this to return the machine mode to use for the type
1      '_FloatN', if EXTENDED is false, or the type '_FloatNx', if
1      EXTENDED is true.  If such a type is not supported, return
1      'opt_scalar_float_mode ()'.  The default version of this hook
1      returns 'SFmode' for '_Float32', 'DFmode' for '_Float64' and
1      '_Float32x' and 'TFmode' for '_Float128', if those modes exist and
1      satisfy the requirements for those types and pass
1      'TARGET_SCALAR_MODE_SUPPORTED_P' and
1      'TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P'; for '_Float64x', it
1      returns the first of 'XFmode' and 'TFmode' that exists and
1      satisfies the same requirements; for other types, it returns
1      'opt_scalar_float_mode ()'.  The hook is only called for values of
1      N and EXTENDED that are valid according to ISO/IEC TS 18661-3:2015;
1      that is, N is one of 32, 64, 128, or, if EXTENDED is false, 16 or
1      greater than 128 and a multiple of 32.
1 
1  -- Target Hook: bool TARGET_FLOATN_BUILTIN_P (int FUNC)
1      Define this to return true if the '_FloatN' and '_FloatNx' built-in
1      functions should implicitly enable the built-in function without
1      the '__builtin_' prefix in addition to the normal built-in function
1      with the '__builtin_' prefix.  The default is to only enable
1      built-in functions without the '__builtin_' prefix for the GNU C
1      langauge.  In strict ANSI/ISO mode, the built-in function without
1      the '__builtin_' prefix is not enabled.  The argument 'FUNC' is the
1      'enum built_in_function' id of the function to be enabled.
1 
1  -- Target Hook: bool TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
1           (machine_mode MODE)
1      Define this to return nonzero for machine modes for which the port
1      has small register classes.  If this target hook returns nonzero
1      for a given MODE, the compiler will try to minimize the lifetime of
1      registers in MODE.  The hook may be called with 'VOIDmode' as
1      argument.  In this case, the hook is expected to return nonzero if
1      it returns nonzero for any mode.
1 
1      On some machines, it is risky to let hard registers live across
1      arbitrary insns.  Typically, these machines have instructions that
1      require values to be in specific registers (like an accumulator),
1      and reload will fail if the required hard register is used for
1      another purpose across such an insn.
1 
1      Passes before reload do not know which hard registers will be used
1      in an instruction, but the machine modes of the registers set or
1      used in the instruction are already known.  And for some machines,
1      register classes are small for, say, integer registers but not for
1      floating point registers.  For example, the AMD x86-64 architecture
1      requires specific registers for the legacy x86 integer
1      instructions, but there are many SSE registers for floating point
1      operations.  On such targets, a good strategy may be to return
1      nonzero from this hook for 'INTEGRAL_MODE_P' machine modes but zero
1      for the SSE register classes.
1 
1      The default version of this hook returns false for any mode.  It is
1      always safe to redefine this hook to return with a nonzero value.
1      But if you unnecessarily define it, you will reduce the amount of
1      optimizations that can be performed in some cases.  If you do not
1      define this hook to return a nonzero value when it is required, the
1      compiler will run out of spill registers and print a fatal error
1      message.
1