2.6.2 エントリ・ポイントのレジスタ宣言の output 引数 |
|
output 引数は,ルーチンがその呼び出し元に返す値を格納するレジスタを示します。多くの場合はそのルーチン自体がレジスタを変更しますが,出力値を代入する別のルーチンをそのルーチンが呼び出す場合もあります。これはパススルー出力テクニックと呼ばれ,呼び出される側のルーチンもそのルーチン・エントリ・レジスタ・セットでそのレジスタを
output として宣言する必要があります。
この引数を使用することで,ルーチンの中で変更されるレジスタの自動的な保護が禁止されます。この引数に指定されているレジスタは,ルーチンによって変更されている場合でも, .CALL_ENTRY ルーチンや .JSB_ENTRY ルーチンで保護されません。
output 引数は,コンパイラに対し,ルーチンの出口で,指定されたレジスタに意味のある値が格納されており,コンパイラが最後にそのレジスタの使用を検出した後でも,そのレジスタを一時レジスタとして使用できないことを知らせます。通常,コンパイラは VAX レジスタ (R2 〜 R12) を一時レジスタとして使用しないため,output 引数にレジスタを指定すると,以下の 2 つの場合にコンパイラの一時レジスタの使用が影響を受けます。
- OpenVMS Alpha システムのみ: 最適化オプション VAXREGS を使用している場合。この最適化を有効にすると, VAX MACRO コードで明示的に使用されていないすべての VAX レジスタをコンパイラが一時レジスタとして使用できるようになります。なお,.JSB32_ENTRY 指示文では,VAXREGS 最適化を使用した場合,コンパイラは常にすべての VAX レジスタが出力として使用されていると仮定します。そのため,VAX レジスタを
output 引数に指定し,コンパイラの一時レジスタとして使用されないようにする必要はありません。
- Alpha または Itanium のレジスタのいずれか (R13 以降) を明示的に使用している場合。
上記のいずれかのケースで,出力として使用されているレジスタを
output 引数に指定しないと,そのレジスタはコンパイラによって一時レジスタとして使用され,出力値が壊れてしまいます。
.JSB32_ENTRY ルーチンでは,デフォルトではどのレジスタも保存されないため, output 引数はコードの文書化のためだけに使用されます。
OpenVMS Alpha システムのみ: VAXREGS の最適化では,すべてのレジスタは出力であるものと見なされるため, output 引数はコードの文書化のためにのみ使用されます。
2.6.3 エントリ・ポイントのレジスタ宣言の scratch 引数 |
|
scratch 引数は,ルーチンの中で使用しているものの,ルーチンの入口と出口で保存および復元をする必要がないレジスタを示します。ルーチンの呼び出し元は,これらのレジスタに出力値が格納されることを期待せず,レジスタが保護されることも期待しません。
この引数を使用すると,ルーチン内で変更されるレジスタが保護されなくなります。この引数に指定されているレジスタは,ルーチン内で変更される場合でも保護されません。
scratch 引数は,コンパイラの一時レジスタの使用にも関係します。レジスタ R13 以降がルーチンのソース・コードで使用されていなければ,コンパイラはこれらのレジスタを一時レジスタとして使用します。 OpenVMS Alpha システムと OpenVMS I64 システムでは, R13 〜 R15 が変更される場合は保護する必要があるため,コンパイラはこれらのレジスタを使用する場合には保護します。
しかし,これらのレジスタが
scratch レジスタ・セット宣言に指定されている場合は,コンパイラは,一時レジスタとしてそれを使用する場合に保護しません。その結果,これらのレジスタは,ルーチンのソースで使用されていなくても,
scratch セットに指定されていれば,ルーチンの出口では壊れている可能性があります。 VAXREGS による最適化を使用した場合は (Alpha システムのみ),これはレジスタ R2 〜 R12 にも適用されます。
.JSB32_ENTRY ルーチンでは,R2 〜 R12 はデフォルトでは保存されないため,
scratch 宣言に指定しても,文書化の意味しかありません。
2.6.4 エントリ・ポイントのレジスタ宣言の preserve 引数 |
|
preserve 引数は,ルーチン呼び出しの前後で保護する必要があるレジスタを指示します。これには,変更され, 64 ビットの内容全体を保存および復元する必要があるレジスタだけを含める必要があります。
preserve 引数を指定すると,コンパイラの .CALL_ENTRY 指示文または .JSB_ENTRY 指示文の処理によってレジスタが自動的に保護されるかどうかにかかわらずレジスタは保護されます。 .JSB32_ENTRY ルーチンでレジスタの 64 ビット全体を保存および復元する唯一の方法でもあります。 R0 と R1 はスクラッチ・レジスタであるため,ルーチンのエントリ・ポイントで
preserve 引数に指定しないかぎり,コンパイラはこれらのレジスタの保存と復元を行いません。
この引数は, output 引数と
scratch 引数より優先されます。
preserve 引数と output 引数または scratch 引数の両方にレジスタを指定すると,コンパイラはレジスタを保護しますが,次の警告を出力します。