Next:Support for Nested Functions, Previous:Stack Layout and Calling Conventions, Up:Target Description Macros and Functions [Contents][Index]
GCC comes with an implementation of<varargs.h> and<stdarg.h> that work without change on machines that pass argumentson the stack. Other machines require their own implementations ofvarargs, and the two machine independent header files must haveconditionals to include it.
ISO<stdarg.h> differs from traditional<varargs.h> mainly inthe calling convention forva_start. The traditionalimplementation takes just one argument, which is the variable in whichto store the argument pointer. The ISO implementation ofva_start takes an additional second argument. The user issupposed to write the last named argument of the function here.
However,va_start should not use this argument. The way to findthe end of the named arguments is with the built-in functions describedbelow.
Use this built-in function to save the argument registers in memory sothat the varargs mechanism can access them. Both ISO and traditionalversions ofva_start must use__builtin_saveregs, unlessyou useTARGET_SETUP_INCOMING_VARARGS (see below) instead.
On some machines,__builtin_saveregs is open-coded under thecontrol of the target hookTARGET_EXPAND_BUILTIN_SAVEREGS. Onother machines, it calls a routine written in assembler language,found inlibgcc2.c.
Code generated for the call to__builtin_saveregs appears at thebeginning 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 startsto use them for its own purposes.
This builtin returns the address of the first anonymous stackargument, as typevoid *. IfARGS_GROW_DOWNWARD, itreturns the address of the location above the first anonymous stackargument. Use it inva_start to initialize the pointer forfetching arguments from the stack. Also use it inva_start toverify that the second parameterlastarg is the last named argumentof the current function.
Since each machine has its own conventions for which data types arepassed in which kind of register, your implementation ofva_arghas to embody these conventions. The easiest way to categorize thespecified data type is to use__builtin_classify_type togetherwithsizeof and__alignof__.
__builtin_classify_type ignores the value ofobject,considering only its data type. It returns an integer describing whatkind of type that is—integer, floating, pointer, structure, and so on.
The filetypeclass.h defines an enumeration that you can use tointerpret the values of__builtin_classify_type.
These machine description macros help implement varargs:
rtxTARGET_EXPAND_BUILTIN_SAVEREGS(void) ¶If defined, this hook produces the machine-specific code for a call to__builtin_saveregs. This code will be moved to the verybeginning of the function, before any parameter access are made. Thereturn value of this function should be an RTX that contains the valueto use as the return of__builtin_saveregs.
voidTARGET_SETUP_INCOMING_VARARGS(cumulative_args_targs_so_far, const function_arg_info&arg, int *pretend_args_size, intsecond_time) ¶This target hook offers an alternative to using__builtin_saveregs and defining the hookTARGET_EXPAND_BUILTIN_SAVEREGS. Use it to store the anonymousregister arguments into the stack so that all the arguments appear tohave been passed consecutively on the stack. Once this is done, you canuse the standard implementation of varargs that works for machines thatpass all their arguments on the stack.
The argumentargs_so_far points to theCUMULATIVE_ARGS datastructure, containing the values that are obtained after processing thenamed arguments. The argumentarg describes the last of these namedarguments. The argumentarg should not be used if the function typesatisfiesTYPE_NO_NAMED_ARGS_STDARG_P, since in that case there areno named arguments and all arguments are accessed withva_arg.
The target hook should do two things: first, push onto the stack all theargument registersnot used for the named arguments, and second,store the size of the data thus pushed into theint-valuedvariable pointed to bypretend_args_size. The value that youstore here will serve as additional offset for setting up the stackframe.
Because you must generate code to push the anonymous arguments atcompile time without knowing their data types,TARGET_SETUP_INCOMING_VARARGS is only useful on machines thathave just a single category of argument register and use it uniformlyfor all data types.
If the argumentsecond_time is nonzero, it means that thearguments of the function are being analyzed for the second time. Thishappens for an inline function, which is not actually compiled until theend of the source file. The hookTARGET_SETUP_INCOMING_VARARGS shouldnot generate any instructions in this case.
boolTARGET_STRICT_ARGUMENT_NAMING(cumulative_args_tca) ¶Define this hook to returntrue if the location where a functionargument is passed depends on whether or not it is a named argument.
This hook controls how thenamed argument toTARGET_FUNCTION_ARGis set for varargs and stdarg functions. If this hook returnstrue, thenamed argument is always true for namedarguments, and false for unnamed arguments. If it returnsfalse,butTARGET_PRETEND_OUTGOING_VARARGS_NAMED returnstrue,then all arguments are treated as named. Otherwise, all named argumentsexcept the last are treated as named.
You need not define this hook if it always returnsfalse.
intTARGET_CALL_OFFSET_RETURN_LABEL(rtx_insn *call_insn) ¶While generating call-site debug info for a CALL insn, or a SEQUENCEinsn starting with a CALL, this target hook is invoked to compute theoffset to be added to the debug label emitted after the call to obtainthe return address that should be recorded as the return PC.
voidTARGET_START_CALL_ARGS(cumulative_args_tcomplete_args) ¶This target hook is invoked while generating RTL for a function call,after the argument values have been computed, and after stack argumentshave been initialized, but before register arguments have been moved intotheir ABI-defined hard register locations. It precedes calls to the relatedhooksTARGET_CALL_ARGS andTARGET_END_CALL_ARGS.The significance of this position in the call expansion is that:
memcpy to copy large arguments), no such subcall will occur betweenthe call to this hook and the generation of the main call instruction.The single argumentcomplete_args is the state of the targetfunction’s cumulative argument information after the final call toTARGET_FUNCTION_ARG.
The hook can be used for things like switching processor mode, in caseswhere different calls need different processor modes. Most ports do notneed to implement anything for this hook.
voidTARGET_CALL_ARGS(cumulative_args_tcomplete_args, rtxloc, treetype) ¶While generating RTL for a function call, this target hook is invoked oncefor each argument passed to the function, either a register returned byTARGET_FUNCTION_ARG or a memory location. It is called justbefore the point where argument registers are stored.
complete_args is the state of the target function’s cumulativeargument information after the final call toTARGET_FUNCTION_ARG.loc is the location of the argument.type is the type ofthe function being called, orNULL_TREE for libcalls.
For functions without arguments, the hook is called once withpc_rtxpassed instead of an argument register.
This functionality can be used to perform special setup of call argumentregisters, if a target needs it. Most ports do not need to implementanything for this hook.
voidTARGET_END_CALL_ARGS(cumulative_args_tcomplete_args) ¶This target hook is invoked while generating RTL for a function call,just after the point where the return reg is copied into a pseudo. Itsignals that all the call argument and return registers for the justemitted call are now no longer in use.complete_args is thestate of the target function’s cumulative argument information afterthe final call toTARGET_FUNCTION_ARG.
Most ports do not need to implement anything for this hook.
boolTARGET_PRETEND_OUTGOING_VARARGS_NAMED(cumulative_args_tca) ¶If you need to conditionally change ABIs so that one works withTARGET_SETUP_INCOMING_VARARGS, but the other works like neitherTARGET_SETUP_INCOMING_VARARGS norTARGET_STRICT_ARGUMENT_NAMING wasdefined, then define this hook to returntrue ifTARGET_SETUP_INCOMING_VARARGS is used,false otherwise.Otherwise, you should not define this hook.
Next:Support for Nested Functions, Previous:Stack Layout and Calling Conventions, Up:Target Description Macros and Functions [Contents][Index]