gccint: Varargs

1 
1 18.10 Implementing the Varargs Macros
1 =====================================
1 
1 GCC comes with an implementation of '<varargs.h>' and '<stdarg.h>' that
1 work without change on machines that pass arguments on the stack.  Other
1 machines require their own implementations of varargs, and the two
1 machine independent header files must have conditionals to include it.
1 
1  ISO '<stdarg.h>' differs from traditional '<varargs.h>' mainly in the
1 calling convention for 'va_start'.  The traditional implementation takes
1 just one argument, which is the variable in which to store the argument
1 pointer.  The ISO implementation of 'va_start' takes an additional
1 second argument.  The user is supposed to write the last named argument
1 of the function here.
1 
1  However, 'va_start' should not use this argument.  The way to find the
1 end of the named arguments is with the built-in functions described
1 below.
1 
1  -- Macro: __builtin_saveregs ()
1      Use this built-in function to save the argument registers in memory
1      so that the varargs mechanism can access them.  Both ISO and
1      traditional versions of 'va_start' must use '__builtin_saveregs',
1      unless you use 'TARGET_SETUP_INCOMING_VARARGS' (see below) instead.
1 
1      On some machines, '__builtin_saveregs' is open-coded under the
1      control of the target hook 'TARGET_EXPAND_BUILTIN_SAVEREGS'.  On
1      other machines, it calls a routine written in assembler language,
1      found in 'libgcc2.c'.
1 
1      Code generated for the call to '__builtin_saveregs' appears at the
1      beginning of the function, as opposed to where the call to
1      '__builtin_saveregs' is written, regardless of what the code is.
1      This is because the registers must be saved before the function
1      starts to use them for its own purposes.
1 
1  -- Macro: __builtin_next_arg (LASTARG)
1      This builtin returns the address of the first anonymous stack
1      argument, as type 'void *'.  If 'ARGS_GROW_DOWNWARD', it returns
1      the address of the location above the first anonymous stack
1      argument.  Use it in 'va_start' to initialize the pointer for
1      fetching arguments from the stack.  Also use it in 'va_start' to
1      verify that the second parameter LASTARG is the last named argument
1      of the current function.
1 
1  -- Macro: __builtin_classify_type (OBJECT)
1      Since each machine has its own conventions for which data types are
1      passed in which kind of register, your implementation of 'va_arg'
1      has to embody these conventions.  The easiest way to categorize the
1      specified data type is to use '__builtin_classify_type' together
1      with 'sizeof' and '__alignof__'.
1 
1      '__builtin_classify_type' ignores the value of OBJECT, considering
1      only its data type.  It returns an integer describing what kind of
1      type that is--integer, floating, pointer, structure, and so on.
1 
1      The file 'typeclass.h' defines an enumeration that you can use to
1      interpret the values of '__builtin_classify_type'.
1 
1  These machine description macros help implement varargs:
1 
1  -- Target Hook: rtx TARGET_EXPAND_BUILTIN_SAVEREGS (void)
1      If defined, this hook produces the machine-specific code for a call
1      to '__builtin_saveregs'.  This code will be moved to the very
1      beginning of the function, before any parameter access are made.
1      The return value of this function should be an RTX that contains
1      the value to use as the return of '__builtin_saveregs'.
1 
1  -- Target Hook: void TARGET_SETUP_INCOMING_VARARGS (cumulative_args_t
1           ARGS_SO_FAR, machine_mode MODE, tree TYPE, int
1           *PRETEND_ARGS_SIZE, int SECOND_TIME)
1      This target hook offers an alternative to using
1      '__builtin_saveregs' and defining the hook
1      'TARGET_EXPAND_BUILTIN_SAVEREGS'.  Use it to store the anonymous
1      register arguments into the stack so that all the arguments appear
1      to have been passed consecutively on the stack.  Once this is done,
1      you can use the standard implementation of varargs that works for
1      machines that pass all their arguments on the stack.
1 
1      The argument ARGS_SO_FAR points to the 'CUMULATIVE_ARGS' data
1      structure, containing the values that are obtained after processing
1      the named arguments.  The arguments MODE and TYPE describe the last
1      named argument--its machine mode and its data type as a tree node.
1 
1      The target hook should do two things: first, push onto the stack
1      all the argument registers _not_ used for the named arguments, and
1      second, store the size of the data thus pushed into the
1      'int'-valued variable pointed to by PRETEND_ARGS_SIZE.  The value
1      that you store here will serve as additional offset for setting up
1      the stack frame.
1 
1      Because you must generate code to push the anonymous arguments at
1      compile time without knowing their data types,
1      'TARGET_SETUP_INCOMING_VARARGS' is only useful on machines that
1      have just a single category of argument register and use it
1      uniformly for all data types.
1 
1      If the argument SECOND_TIME is nonzero, it means that the arguments
1      of the function are being analyzed for the second time.  This
1      happens for an inline function, which is not actually compiled
1      until the end of the source file.  The hook
1      'TARGET_SETUP_INCOMING_VARARGS' should not generate any
1      instructions in this case.
1 
1  -- Target Hook: bool TARGET_STRICT_ARGUMENT_NAMING (cumulative_args_t
1           CA)
1      Define this hook to return 'true' if the location where a function
1      argument is passed depends on whether or not it is a named
1      argument.
1 
1      This hook controls how the NAMED argument to 'TARGET_FUNCTION_ARG'
1      is set for varargs and stdarg functions.  If this hook returns
1      'true', the NAMED argument is always true for named arguments, and
1      false for unnamed arguments.  If it returns 'false', but
1      'TARGET_PRETEND_OUTGOING_VARARGS_NAMED' returns 'true', then all
1      arguments are treated as named.  Otherwise, all named arguments
1      except the last are treated as named.
1 
1      You need not define this hook if it always returns 'false'.
1 
1  -- Target Hook: void TARGET_CALL_ARGS (rtx, TREE)
1      While generating RTL for a function call, this target hook is
1      invoked once for each argument passed to the function, either a
1      register returned by 'TARGET_FUNCTION_ARG' or a memory location.
1      It is called just before the point where argument registers are
1      stored.  The type of the function to be called is also passed as
1      the second argument; it is 'NULL_TREE' for libcalls.  The
1      'TARGET_END_CALL_ARGS' hook is invoked just after the code to copy
1      the return reg has been emitted.  This functionality can be used to
1      perform special setup of call argument registers if a target needs
1      it.  For functions without arguments, the hook is called once with
1      'pc_rtx' passed instead of an argument register.  Most ports do not
1      need to implement anything for this hook.
1 
1  -- Target Hook: void TARGET_END_CALL_ARGS (void)
1      This target hook is invoked while generating RTL for a function
1      call, just after the point where the return reg is copied into a
1      pseudo.  It signals that all the call argument and return registers
1      for the just emitted call are now no longer in use.  Most ports do
1      not need to implement anything for this hook.
1 
1  -- Target Hook: bool TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1           (cumulative_args_t CA)
1      If you need to conditionally change ABIs so that one works with
1      'TARGET_SETUP_INCOMING_VARARGS', but the other works like neither
1      'TARGET_SETUP_INCOMING_VARARGS' nor 'TARGET_STRICT_ARGUMENT_NAMING'
1      was defined, then define this hook to return 'true' if
1      'TARGET_SETUP_INCOMING_VARARGS' is used, 'false' otherwise.
1      Otherwise, you should not define this hook.
1 
1  -- Target Hook: rtx TARGET_LOAD_BOUNDS_FOR_ARG (rtx SLOT, rtx ARG, rtx
1           SLOT_NO)
1      This hook is used by expand pass to emit insn to load bounds of ARG
1      passed in SLOT.  Expand pass uses this hook in case bounds of ARG
1      are not passed in register.  If SLOT is a memory, then bounds are
1      loaded as for regular pointer loaded from memory.  If SLOT is not a
1      memory then SLOT_NO is an integer constant holding number of the
1      target dependent special slot which should be used to obtain
1      bounds.  Hook returns RTX holding loaded bounds.
1 
1  -- Target Hook: void TARGET_STORE_BOUNDS_FOR_ARG (rtx ARG, rtx SLOT,
1           rtx BOUNDS, rtx SLOT_NO)
1      This hook is used by expand pass to emit insns to store BOUNDS of
1      ARG passed in SLOT.  Expand pass uses this hook in case BOUNDS of
1      ARG are not passed in register.  If SLOT is a memory, then BOUNDS
1      are stored as for regular pointer stored in memory.  If SLOT is not
1      a memory then SLOT_NO is an integer constant holding number of the
1      target dependent special slot which should be used to store BOUNDS.
1 
1  -- Target Hook: rtx TARGET_LOAD_RETURNED_BOUNDS (rtx SLOT)
1      This hook is used by expand pass to emit insn to load bounds
1      returned by function call in SLOT.  Hook returns RTX holding loaded
1      bounds.
1 
1  -- Target Hook: void TARGET_STORE_RETURNED_BOUNDS (rtx SLOT, rtx
1           BOUNDS)
1      This hook is used by expand pass to emit insn to store BOUNDS
1      returned by function call into SLOT.
1 
1  -- Target Hook: rtx TARGET_CHKP_FUNCTION_VALUE_BOUNDS (const_tree
1           RET_TYPE, const_tree FN_DECL_OR_TYPE, bool OUTGOING)
1      Define this to return an RTX representing the place where a
1      function returns bounds for returned pointers.  Arguments meaning
1      is similar to 'TARGET_FUNCTION_VALUE'.
1 
1  -- Target Hook: void TARGET_SETUP_INCOMING_VARARG_BOUNDS
1           (cumulative_args_t ARGS_SO_FAR, machine_mode MODE, tree TYPE,
1           int *PRETEND_ARGS_SIZE, int SECOND_TIME)
1      Use it to store bounds for anonymous register arguments stored into
1      the stack.  Arguments meaning is similar to
1      'TARGET_SETUP_INCOMING_VARARGS'.
1