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