日本-日本語 |
|
|
|
OpenVMS マニュアル |
|
HP OpenVMS MACRO コンパイラ
|
目次 | 索引 |
この付録では,以下の内容について説明します。
これらのマクロは,ディレクトリ SYS$LIBRARY:STARLET.MLB にあり,アプリケーション・コードとシステム・コードの両方で使用することができます。
ページ・マクロは,64 ビット・アドレスをサポートしています。このサポートは,QUAD=NO/YES パラメータによって提供されます。
これらのマクロで特定の引数を使用することで,レジスタ・セットを指定できます。レジスタ・セットを表現するには,次の例のようにレジスタをコンマで区切り,山括弧で囲みます。
<R1,R2,R3> |
レジスタ・セットにレジスタが 1 つしか含まれない場合は,山括弧は不要です。
以下のマクロは,64 ビット・アドレスを操作するために使用します。
E.1 64 ビット・アドレスを操作するためのマクロ
$SETUP_CALL64
呼び出し手順を初期化します。
$SETUP_CALL64 arg_count, inline=true | false
arg_count
呼び出しでの引数の数です。inline
TRUE の場合,JSB ルーチンを作成するのではなく,インライン展開します。引数の数が, OpenVMS Alpha で 6 以下, OpenVMS I64 で 8 以下の場合は,デフォルトは inline=true です。
このマクロは,64 ビット呼び出しの状態を初期化します。 $PUSH_ARG64 や $CALL64 を使用する前に使用する必要があります。引数の数が, OpenVMS Alpha で 6 以下, OpenVMS I64 で 8 以下の場合は,コードは常にインラインになります。
デフォルトでは,引数の数が OpenVMS Alpha で 7 以上, OpenVMS I64 で 9 以上の場合,このマクロは実際の呼び出しを行うために呼び出される JSB ルーチンを作成します。ただし,インライン・オプション inline=true が指定されていると,コードはインラインで生成されます。
このオプションは,このマクロを使用するコードのスタックの深さが固定の場合にのみ有効にしてください。 RUNTIMSTK メッセージまたは VARSIZSTK メッセージがこれまで報告されたことがない場合は,スタックの深さが固定であると考えることができます。そうでない場合は,スタック・アラインメントが少なくともクォドワードでなければ,呼び出されたルーチンと,それが呼び出すすべてのもので多数のアラインメント・フォルトが発生します。デフォルトの動作 (inline=false) では,この問題はありません。
引数の数が OpenVMS Alpha で 7 以上, OpenVMS I64 で 9 以上の場合, $SETUP_CALL64 とそれに対応する $CALL64 の間で AP や SP を参照することはできません。これは,$CALL64 コードが独立した JSB ルーチンにある可能性があるためです。また,一時レジスタ (R16 以降) は, $SETUP_CALL64 を呼び出すと内容が変わってしまう可能性があります。ただし, R16 〜 R12 がすでに設定済みの引数レジスタと干渉する場合を除き (Alpha のみ),一時レジスタをこの範囲で使用することができます。干渉する場合は,より番号の大きな一時レジスタを使用してください。
注意
$SETUP_CALL64,$PUSH_ARG64,および $CALL64 マクロは,インライン・シーケンスで使用するように設計されています。つまり, $SETUP_CALL64/$PUSH_ARG64/$CALL64 シーケンスの途中に分岐したり, $PUSH_ARG64 マクロの前後で分岐したり, $CALL64 を呼び出さずにこのシーケンスから外に分岐することはできません。
$PUSH_ARG64 |
呼び出しのための引数プッシュに相当する動作を行います。
$PUSH_ARG64 argument
argument
プッシュする引数です。
このマクロは,64 ビット呼び出し用に 64 ビット引数をプッシュします。 $PUSH_ARG64 を使用する前に,マクロ $SETUP_CALL64 を使用する必要があります。引数はアラインされたクォドワードとして読み込まれます。つまり, $PUSH_ARG64 4(R0) は 4(R0) の位置にあるクォドワードを読み込み,そのクォドワードをプッシュします。インデックス付きの操作はクォドワード・モードで実行されます。
メモリから読み込んだロングワード値をクォドワードとしてプッシュするには,まずロングワード命令を使用してレジスタに移動し,次にレジスタに対して $PUSH_ARG64 を使用します。同様に,アラインされていない事が分かっているクォドワード値をプッシュするには,まず一時レジスタに移動し,その後 $PUSH_ARG64 を使用します。
呼び出しに含まれている引数の数が, OpenVMS Alpha で 7 以上, OpenVMS I64 で 9 以上の場合は,このマクロは引数の中で SP や AP が参照されていないかチェックします。
呼び出しに含まれている引数の数が, OpenVMS Alpha で 7 以上, OpenVMS I64 で 9 以上の場合は, SP 参照は行うことができず, AP 参照はインライン・オプションを使用している場合にのみ行えます。
OpenVMS Alpha システムのみ: マクロは,現在の $CALL64 に対してすでに設定されている引数レジスタの参照もチェックします。このような参照が見つかると,警告が報告され, $PUSH_ARG64 の中でソースとして使用する前に引数レジスタを上書きしないように注意が促されます。
OpenVMS Alpha システムのみ: 引数の数が 6 以下の場合,同じチェックが AP 参照に対して行われます。参照自体は可能ですが,それを使用する前にプログラムが上書きしてしまうのを防ぐことは,コンパイラにはできません。そのため,このような参照が見つかると,情報メッセージが出力されます。
OpenVMS Alpha システムのみ: オペランドで,名前に R16 〜 R21 のいずれかの文字列が含まれたシンボル (レジスタ参照ではない) が使用されていると,このマクロで誤ってエラーが出力されることがあります。たとえば,R21 が設定された後で $PUSH_ARG64 SAVED_R21 を呼び出すと,このマクロは,引数レジスタの上書きに関する情報メッセージを誤って出力します。
また,$PUSH_ARG64 は条件付きコード内では使用できません。 $PUSH_ARG64 は,残りの引数の個数など,いくつかのシンボルを更新します。 $SETUP_CALL64/$CALL64 シーケンスの途中に, $PUSH_ARG64 の前後で分岐するコードを記述すると,正常に機能しません。
$CALL64 |
ターゲット・ルーチンを呼び出します。
$CALL64 call_target
call_target
呼び出すルーチンです。
このマクロは,$SETUP_CALL64 を使用して引数の個数が指定され, $PUSH_ARG64 を使用してクォドワード引数がプッシュされたものと見なして,指定されたルーチンを呼び出します。このマクロは,プッシュの回数が,セットアップの呼び出しで指定された個数と一致するかどうかを確認します。call_target オペランドは, AP ベースや SP ベースであってはなりません。
E.2 符号拡張と記述子の形式をチェックするためのマクロ |
以下のマクロは,特定の値をチェックし,チェック結果に基づいてプログラム・フローを変更するために使用します。
$IS_32BITS |
64 ビット値の下位 32 ビットの符号拡張をチェックし,チェック結果に基づいてプログラム・フローを変更します。
$IS_32BITS quad_arg, leq_32bits, gtr_32bits, temp_reg=22
quad_arg
レジスタまたはアラインされたクォドワード・メモリ領域にある 64 ビット・データ。leq_32bits
quad_arg が 32 ビットの符号拡張値の場合に分岐する分岐先ラベル。gtr_32bits
quad_arg が 32 ビットよりも大きな場合に分岐する分岐先ラベル。temp_reg=22
ソース値の下位ロングワードを保持するための一時レジスタとして使用するレジスタ。デフォルトは R22。
$IS_32BITS は,64 ビット値の下位 32 ビットの符号拡張をチェックし,チェック結果に基づいてプログラム・フローを変更します。
#1 |
---|
$is_32bits R9, 10$ |
この例では,デフォルトの一時レジスタ R22 を使用し,コンパイラは R9 に格納されている 64 ビット値の下位 32 ビットの符号拡張をチェックします。分岐の種類とテストの結果に応じて,プログラムは分岐するかそのまま続行します。
#2 |
---|
$is_32bits 4(R8), 20$, 30$, R28 |
この例では,R28 を一時レジスタとして使用し, 4(R8) に格納されている 64 ビット値の下位 32 ビットの符号拡張をチェックし,チェック結果に基づいて 20$ または 30$ に分岐します。
$IS_DESC64 |
指定された記述子をテストして64 ビット形式の記述子かどうかを判断し,テスト結果に基づいてプログラム・フローを変更します。
$IS_DESC64 desc_addr, target, size=long | quad
desc_addr
テストする記述子のアドレスです。target
記述子が 64 ビット形式の場合に分岐する分岐先ラベルです。size=long|quad
記述子を指すアドレスのサイズです。デフォルト値は size=long です。
$IS_DESC64 は, 64 ビット記述子と 32 ビット記述子を区別するフィールドをテストします。 64 ビット形式の場合は,指定したターゲットに分岐します。テストするアドレスは,size=quad を指定しないかぎりロングワードとして読み込まれます。
#1 |
---|
$is_desc64 r9, 10$ |
この例では,R9 が指す記述子をテストし, 64 ビット形式である場合は,10$ に分岐します。
#2 |
---|
$is_desc64 8(r0), 20$, size=quad |
この例では,8(R0) にあるクォドワードを読み込み,それが指す記述子をテストします。 64 ビット形式である場合は,20$ に分岐します。
索引 | 目次 |
|