Next: , Previous: Elimination, Up: Stack and Calling


17.10.6 在栈上传递函数参数

该节的宏控制如何在栈上传递参数。关于控制在寄存器中传递特定参数的其它宏, 参见后续的章节。

— Target Hook: bool TARGET_PROMOTE_PROTOTYPES (tree fntype)

该target钩子返回true,如果在函数原型中声明的一个参数, 为整型的并且比int小,应该作为int来传递。 除了能够避免一些不匹配的错误以外,其还能在特定机器上生成更好的代码。 缺省为不提升原型。

— Macro: PUSH_ARGS

一个C表达式。如果非0,则将使用push insn来传递输出参数。 如果target机器不具有push指令,则设置其为0。这将指示GCC使用替代的策略: 分配整个参数块然后将参数存进去。当PUSH_ARGS为非0时, PUSH_ROUNDING也必须被定义。

— Macro: PUSH_ARGS_REVERSED

一个C表达式。如果非0,则函数参数将按照从最后一个到第一个的顺序来求值, 而不是从第一个到最后一个。如果该宏没被定义,其缺省为PUSH_ARGS, 在栈和args按照相反的顺序进行增长的target上,否则为0。

— Macro: PUSH_ROUNDING (npushed)

一个C表达式,其为当一个指令试图压入npushed个字节时,实际压入栈中的字节数。

在一些机器上,定义

          #define PUSH_ROUNDING(BYTES) (BYTES)

便可以满足。但是在其它机器上,指令压入一个字节时, 而为了保持对齐实际压入了两个字节。则定义应该为

          #define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1)

— Macro: ACCUMULATE_OUTGOING_ARGS

一个C表达式。如果非0,则为输出参数中将被计算并放进变量 current_function_outgoing_args_size所需要的空间最大数目。 对于每个调用,将不会有空间被压入栈中;替代的,函数序言应该增加栈帧的大小。

同时设置PUSH_ARGSACCUMULATE_OUTGOING_ARGS是不合适的。

— Macro: REG_PARM_STACK_SPACE (fndecl)

定义该宏,如果函数应该假设参数的栈空间已经被分配, 即使它们的值是在寄存器中被传递的。

该宏的值是一个fndecl表示的函数在寄存器中传递的参数的保留空间的大小, 字节为单位,其可以为0如果GCC在调用一个库函数。

该空间可以被调用者分配,或者为机器相关的栈帧的一部分: 这由OUTGOING_REG_PARM_STACK_SPACE决定。

— Macro: OUTGOING_REG_PARM_STACK_SPACE (fntype)

定义该宏为一个非0值,如果分配在寄存器中传递的参数的保留空间,是由调用者负责。

如果ACCUMULATE_OUTGOING_ARGS被定义, 则该宏控制这些参数的空间是否算在current_function_outgoing_args_size中。

— Macro: STACK_PARMS_IN_REG_PARM_AREA

定义该宏,如果REG_PARM_STACK_SPACE被定义, 但是栈参数不跳过其所指定的区域。

通常,当一个参数没有在寄存器中传递时, 其被放在REG_PARM_STACK_SPACE区域之外的栈上。 定义该宏来抑制这种行为并使得在栈上传递的参数按照它的自然位置。

— Target Hook: int TARGET_RETURN_POPS_ARGS (tree fundecl, tree funtype, int size)

This target hook returns the number of bytes of its own arguments that a function pops on returning, or 0 if the function pops no arguments and the caller must therefore pop them all after the function returns.

fundecl is a C variable whose value is a tree node that describes the function in question. Normally it is a node of type FUNCTION_DECL that describes the declaration of the function. From this you can obtain the DECL_ATTRIBUTES of the function.

funtype is a C variable whose value is a tree node that describes the function in question. Normally it is a node of type FUNCTION_TYPE that describes the data type of the function. From this it is possible to obtain the data types of the value and arguments (if known).

When a call to a library function is being considered, fundecl will contain an identifier node for the library function. Thus, if you need to distinguish among various library functions, you can do so by their names. Note that “library function” in this context means a function used to perform arithmetic, whose name is known specially in the compiler and was not mentioned in the C code being compiled.

size is the number of bytes of arguments passed on the stack. If a variable number of bytes is passed, it is zero, and argument popping will always be the responsibility of the calling function.

On the VAX, all functions always pop their arguments, so the definition of this macro is size. On the 68000, using the standard calling convention, no functions pop their arguments, so the value of the macro is always 0 in this case. But an alternative calling convention is available in which functions that take a fixed number of arguments pop them but other functions (such as printf) pop nothing (the caller pops all). When this convention is in use, funtype is examined to determine whether a function takes a fixed number of arguments.

— Macro: CALL_POPS_ARGS (cum)

一个C表达式,指示一个调用序列从栈中弹出的字节数目。 其被加到RETURN_POPS_ARGS的值中,当编译一个函数调用时。

cum为一个变量,为被调用函数的所有参数的累积。

在特定的体系结构上,例如SH5,一个调用蹦床被用于弹出栈上特定的寄存器, 根据被传递给函数的参数。因为这是调用方的属性,而不是被调用函数的, 所以RETURN_POPS_ARGS不太适合。