[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

17.7.5 関数の引数のスタック渡し

この節で説明するマクロ群は、引数がスタック上にどのように渡されるかを 制御する。引数のレジスタ渡しを制御するマクロについては、次の節で 参照のこと。

PROMOTE_PROTOTYPES

プロトタイプ宣言で int 型より小さい整数型として宣言されている 引数を、実際には int 型として渡すべきである場合には このマクロを定義する。ある種の型の不一致によるエラーを避けるだけでなく、 マシンによってはより良いコードを生成することがある。

PUSH_ROUNDING (npushed)

ある命令が npushed バイトをプッシュしようとしたときに 実際にスタックにプッシュされるバイト数を表す C の式を定義する。

ターゲットマシンにプッシュ命令がないのなら、このマクロは定義しないこと。 このマクロが定義されていなければ、GNU CC は別の戦略をとる。 つまり、引数全体のブロックを割り当て、引数をそこに格納する。

マシンによっては、

 
#define PUSH_ROUNDING(BYTES) (BYTES)

という定義で充分である。 しかし、別のマシンでは、一バイトをプッシュするように見える命令が 実際にはアラインメントを維持するために二バイトをプッシュすることがある。 そういう場合は以下のように定義する。

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

このマクロが定義されていると、出力引数に必要とされるメモリスペースの 最大量は、計算されたうえで、current_function_outgoing_args_size という変数に置かれる。 各呼び出しではスタックにはスペースはプッシュされない。 代わりに、呼び出される関数のプロローグがこの量だけスタックフレームの 大きさを増やす必要がある。

PUSH_ROUNDINGACCUMULATE_OUTGOING_ARGS の両方を 定義するのは正しくない。

REG_PARM_STACK_SPACE (fndecl)

引数の値がレジスタで渡される場合でも、その引数用にスタックが 割り当てられていると、関数の方で仮定すべきであるなら、このマクロを 定義する。

このマクロの値は、fndecl で表される関数にレジスタで渡される 引数用の領域の大きさをバイト数で表したものである。 この値は、GNU CC がライブラリ関数を呼び出すときはゼロになりうる。

この領域は呼びだし側で割り当てることも可能だし、マシン依存のスタック フレームの一部であっても良い。OUTGOING_REG_PARM_STACK_SPACE で どちらかを指定する。

MAYBE_REG_PARM_STACK_SPACE
FINAL_REG_PARM_STACK_SPACE (const_size, var_size)

関数が、その引数値がレジスタで渡される場合でもスタックスペースを 割り当てる場合は、上記のマクロに加えてこれらのマクロを定義する。 これらのマクロは、レジスタにある引数用に割り当てられたスタックスペース が、その関数宣言に依存しない単なる定数ではない場合に使うべきである。

最初のマクロの値は、レジスタで渡される引数用に予約されると最初に 仮定した領域の大きさをバイト数で表したものである。

二番目のマクロの値は、レジスタで渡される引数用に予約される領域の 実際の大きさをバイト数で表したものである。このマクロは引数を 二つ取る。スタック上に取られる固定長の引数のバイト数を表す整数と、 スタック上に取られる可変長の引数のバイト数を表すツリーである。

これらのマクロが定義されていると、REG_PARM_STACK_SPACE は 以下の関数に対してだけ呼び出される。すなわち、libcall 関数、現在の関数、 それに、このようなスタックスペースを割り当てなければならないことが 知られているとき呼び出される関数である。 どの場合にも、このマクロの値は簡単に計算できる。

呼び出された関数がこのようなスタックスペースを必要とするか、必要な 場合はどれだけのスペースを予約すれば良いのかを決めるときに、GNU CC は REG_PARM_STACK_SPACE の代わりにこの二つのマクロを使う。

OUTGOING_REG_PARM_STACK_SPACE

レジスタで渡された引数用の予約領域を割り当てるのが、呼び出し側の 責任であるなら、これを定義する。

ACCUMULATE_OUTGOING_ARGS が定義されている場合は、 このマクロは、これらの引数用領域を current_function_outgoing_args_size の値に含めるかどうかを 制御する。

STACK_PARMS_IN_REG_PARM_AREA

REG_PARM_STACK_SPACE は定義されているが、スタック上のパラメータが それで指定された領域をスキップしない場合はこのマクロを定義する。

普通、パラメータがレジスタで渡されない場合は、REG_PARM_STACK_SPACE 領域を越えたスタック上に置かれる。このマクロを定義するとこの動作を 抑制し、パラメータをスタック上の自然な位置に渡すようにする。

RETURN_POPS_ARGS (fundecl, funtype, stack-size)

関数が戻るときにポップする自分自身の引数のバイト数を表す C の式。 あるいは、その関数は自分では引数をポップしないために呼びだし側が、 その関数が戻った後で、全部ポップしなければならないときは、0 である。

fundecl は一個の C の変数であり、その値は 問題の関数を記述する木ノードである。 通常、このノードの型は、関数の宣言を記述する FUNCTION_DECL である。 これから、その関数の DECL_MACHINE_ATTRIBUTES を得ることができる。

funtype は一個の C の変数であり、その値は 問題の関数を記述する木ノードである。 通常、このノードの型は、関数のデータ型を 記述する FUNCTION_TYPE である。 これから、戻り値と引数(既知であれば)のデータ型を得ることができる。

ライブラリ関数の呼び出しを考えるときは、fundecl には そのライブラリ関数の識別子ノードが入る。つまり、色々なライブラリ関数を 区別する必要があるときは、名前で区別することができるのである。 ここで「ライブラリ関数」というのは、算術演算を行なうのに使われる関数で、 コンパイラが特別にその名前を知っているものであり、コンパイルされる C のコードには現れないものである。

stack-size は、スタックで渡される引数のバイト数である。 可変のバイト数が渡される場合は、stack-size はゼロになり、 引数のポップは常に呼び出し側関数の責任になる。

VAX の場合は、全ての関数が引数をポップするので、このマクロの定義は stack-size になる。68000 では、標準の呼び出し規約を使うと、 引数をポップする関数はないので、このマクロの値は常にゼロになる。 ただし、別の呼び出し規約も利用可能で、その場合固定数の引数を取る関数は その引数をポップするが、それ以外の関数(例えば printf) は 何もポップしない(呼び出し側が全部ポップする)。 後者の規約が使われるときは、funtype を調べて、関数が固定数の 引数を取るかどうかが決定される。


This document was generated using texi2html 1.78.