GNU Info

Info Node: (gcc-295.info)Varargs

(gcc-295.info)Varargs


Next: Trampolines Prev: Stack and Calling Up: Target Macros
Enter node , (file) or (file)node

Implementing the Varargs Macros
===============================

   GNU CC comes with an implementation of `varargs.h' and `stdarg.h'
that work without change on machines that pass arguments on the stack.
Other machines require their own implementations of varargs, and the
two machine independent header files must have conditionals to include
it.

   ANSI `stdarg.h' differs from traditional `varargs.h' mainly in the
calling convention for `va_start'.  The traditional implementation
takes just one argument, which is the variable in which to store the
argument pointer.  The ANSI implementation of `va_start' takes an
additional second argument.  The user is supposed to write the last
named argument of the function here.

   However, `va_start' should not use this argument.  The way to find
the end of the named arguments is with the built-in functions described
below.

`__builtin_saveregs ()'
     Use this built-in function to save the argument registers in
     memory so that the varargs mechanism can access them.  Both ANSI
     and traditional versions of `va_start' must use
     `__builtin_saveregs', unless you use `SETUP_INCOMING_VARARGS' (see
     below) instead.

     On some machines, `__builtin_saveregs' is open-coded under the
     control of the macro `EXPAND_BUILTIN_SAVEREGS'.  On other machines,
     it calls a routine written in assembler language, found in
     `libgcc2.c'.

     Code generated for the call to `__builtin_saveregs' appears at the
     beginning of the function, as opposed to where the call to
     `__builtin_saveregs' is written, regardless of what the code is.
     This is because the registers must be saved before the function
     starts to use them for its own purposes.

`__builtin_args_info (CATEGORY)'
     Use this built-in function to find the first anonymous arguments in
     registers.

     In general, a machine may have several categories of registers
     used for arguments, each for a particular category of data types.
     (For example, on some machines, floating-point registers are used
     for floating-point arguments while other arguments are passed in
     the general registers.)  To make non-varargs functions use the
     proper calling convention, you have defined the `CUMULATIVE_ARGS'
     data type to record how many registers in each category have been
     used so far

     `__builtin_args_info' accesses the same data structure of type
     `CUMULATIVE_ARGS' after the ordinary argument layout is finished
     with it, with CATEGORY specifying which word to access.  Thus, the
     value indicates the first unused register in a given category.

     Normally, you would use `__builtin_args_info' in the implementation
     of `va_start', accessing each category just once and storing the
     value in the `va_list' object.  This is because `va_list' will
     have to update the values, and there is no way to alter the values
     accessed by `__builtin_args_info'.

`__builtin_next_arg (LASTARG)'
     This is the equivalent of `__builtin_args_info', for stack
     arguments.  It returns the address of the first anonymous stack
     argument, as type `void *'. If `ARGS_GROW_DOWNWARD', it returns
     the address of the location above the first anonymous stack
     argument.  Use it in `va_start' to initialize the pointer for
     fetching arguments from the stack.  Also use it in `va_start' to
     verify that the second parameter LASTARG is the last named argument
     of the current function.

`__builtin_classify_type (OBJECT)'
     Since each machine has its own conventions for which data types are
     passed in which kind of register, your implementation of `va_arg'
     has to embody these conventions.  The easiest way to categorize the
     specified data type is to use `__builtin_classify_type' together
     with `sizeof' and `__alignof__'.

     `__builtin_classify_type' ignores the value of OBJECT, considering
     only its data type.  It returns an integer describing what kind of
     type that is--integer, floating, pointer, structure, and so on.

     The file `typeclass.h' defines an enumeration that you can use to
     interpret the values of `__builtin_classify_type'.

   These machine description macros help implement varargs:

`EXPAND_BUILTIN_SAVEREGS (ARGS)'
     If defined, is a C expression that produces the machine-specific
     code for a call to `__builtin_saveregs'.  This code will be moved
     to the very beginning of the function, before any parameter access
     are made.  The return value of this function should be an RTX that
     contains the value to use as the return of `__builtin_saveregs'.

     The argument ARGS is a `tree_list' containing the arguments that
     were passed to `__builtin_saveregs'.

     If this macro is not defined, the compiler will output an ordinary
     call to the library function `__builtin_saveregs'.

`SETUP_INCOMING_VARARGS (ARGS_SO_FAR, MODE, TYPE, PRETEND_ARGS_SIZE, SECOND_TIME)'
     This macro offers an alternative to using `__builtin_saveregs' and
     defining the macro `EXPAND_BUILTIN_SAVEREGS'.  Use it to store the
     anonymous register arguments into the stack so that all the
     arguments appear to have been passed consecutively on the stack.
     Once this is done, you can use the standard implementation of
     varargs that works for machines that pass all their arguments on
     the stack.

     The argument ARGS_SO_FAR is the `CUMULATIVE_ARGS' data structure,
     containing the values that obtain after processing of the named
     arguments.  The arguments MODE and TYPE describe the last named
     argument--its machine mode and its data type as a tree node.

     The macro implementation should do two things: first, push onto the
     stack all the argument registers *not* used for the named
     arguments, and second, store the size of the data thus pushed into
     the `int'-valued variable whose name is supplied as the argument
     PRETEND_ARGS_SIZE.  The value that you store here will serve as
     additional offset for setting up the stack frame.

     Because you must generate code to push the anonymous arguments at
     compile time without knowing their data types,
     `SETUP_INCOMING_VARARGS' is only useful on machines that have just
     a single category of argument register and use it uniformly for
     all data types.

     If the argument SECOND_TIME is nonzero, it means that the
     arguments of the function are being analyzed for the second time.
     This happens for an inline function, which is not actually
     compiled until the end of the source file.  The macro
     `SETUP_INCOMING_VARARGS' should not generate any instructions in
     this case.

`STRICT_ARGUMENT_NAMING'
     Define this macro to be a nonzero value if the location where a
     function argument is passed depends on whether or not it is a
     named argument.

     This macro controls how the NAMED argument to `FUNCTION_ARG' is
     set for varargs and stdarg functions.  If this macro returns a
     nonzero value, the NAMED argument is always true for named
     arguments, and false for unnamed arguments.  If it returns a value
     of zero, but `SETUP_INCOMING_VARARGS' is defined, then all
     arguments are treated as named.  Otherwise, all named arguments
     except the last are treated as named.

     You need not define this macro if it always returns zero.

`PRETEND_OUTGOING_VARARGS_NAMED'
     If you need to conditionally change ABIs so that one works with
     `SETUP_INCOMING_VARARGS', but the other works like neither
     `SETUP_INCOMING_VARARGS' nor `STRICT_ARGUMENT_NAMING' was defined,
     then define this macro to return nonzero if
     `SETUP_INCOMING_VARARGS' is used, zero otherwise.  Otherwise, you
     should not define this macro.


automatically generated by info2www version 1.2.2.9