日本-日本語 |
|
|
|
OpenVMS マニュアル |
|
HP OpenVMS MACRO コンパイラ
|
目次 | 索引 |
第 5 章
MACRO の 64 ビット・アドレッシングのサポート
この章では,MACRO コンパイラとそれに関連する構成要素による 64 ビット・アドレッシングのサポートについて説明します。
この章のトピックは以下のとおりです。
MACRO コンパイラでは,64 ビット・アドレッシングをサポートする構成要素が提供されています。
64 ビット・アドレッシングは, OpenVMS Alpha または OpenVMS I64 に移植したコードでのみ使用してください。 OpenVMS Alpha または OpenVMS I64 上で新たに開発する場合は,高級言語を使用することをお勧めします。
信頼性が高く保守が簡単なコードを生成できるように提供されている,修飾子,マクロ,指示文,ビルトインを使用して, 64 ビット・アドレッシングをコード中で明示的に行う必要があります。
表 5-1 に, MACRO プログラミングでの 64 ビット・アドレッシングのサポートを提供する構成要素を示します。
構成要素 | 説明 |
---|---|
$SETUP_CALL64 | 呼び出し手順を初期化するマクロ |
$PUSH_ARG64 | 引数のプッシュ相当の処理を実行するマクロ |
$CALL64 | 対象ルーチンを呼び出すマクロ |
$IS_32BITS | 64 ビット値の下位 32 ビットの符号拡張をチェックするマクロ |
$IS_DESC64 | 記述子が 64 ビット形式の記述子かどうかを判断するマクロ |
QUAD=NO/YES | 64 ビット仮想アドレスをサポートするためのページ・マクロのパラメータ |
/ENABLE=QUADWORD | 64 ビット・アドレスの計算を含むように拡張された QUADWORD パラメータ |
.CALL_ENTRY QUAD_ARGS=TRUE|FALSE | QUAD_ARGS=TRUE|FALSE。引数リストに対するクォドワード参照の有無を示す ( 第 5.3 節 を参照) |
.ENABLE QUADWORD
.DISABLE QUADWORD |
64 ビット・アドレスの計算を含むように拡張された QUADWORD パラメータ |
EVAX_SEXTL | 64 ビット値の下位 32 ビットを符号拡張してデスティネーションに格納するビルトイン |
EVAX_CALLG_64 | 可変サイズの引数リストを使用した 64 ビット呼び出しをサポートするためのビルトイン |
$RAB64 および $RAB64_STORE | 64 ビット・アドレス空間のバッファを使用するための RMS マクロ |
64 ビット値を渡すために使用する方法は,引数リストのサイズが固定か可変かによって変わります。ここでは,これらの方法について説明します。
固定サイズの引数リストを使用した呼び出しでは, 表 5-2 に示すマクロを使用します。
5.2.1 固定サイズの引数リストを使用した呼び出し
使用する手順 | 使用するマクロ |
---|---|
1. 呼び出し手順の初期化 | $SETUP_CALL64 |
2. 呼び出し引数の「プッシュ」 | $PUSH_ARG64 |
3. 対象ルーチンの呼び出し | $CALL64 |
これらのマクロの使用例を以下に示します。引数は逆の順序でプッシュされる点に注意してください。これは,32 ビットの PUSHL 命令を使う場合でも同様です。
MOVL 8(AP), R5 ; fetch a longword to be passed $SETUP_CALL64 3 ; Specify three arguments in call $PUSH_ARG64 8(R0) ; Push argument #3 $PUSH_ARG64 R5 ; Push argument #2 $PUSH_ARG64 #8 ; Push argument #1 $CALL64 some_routine ; Call the routine |
$SETUP_CALL64 マクロは,64 ビット呼び出しの状態を初期化します。 $PUSH_ARG64 や $CALL64 を使用する前に必要です。引数の数が OpenVMS Alpha では 6, OpenVMS I64 では 8 を超える場合は,このマクロはローカルな JSB ルーチンを作成します ( このルーチンは,呼び出しを実行するために呼び出されます)。そうでない場合は,引数のロードと呼び出しはインラインとなり,非常に効率が良くなります。 $SETUP_CALL64 で指定する引数カウントには,シャープ (#) は含まれないことに注意してください。 (標準的な呼び出し手順では,スタックはオクタワードでアラインされ,スタックの先頭に引数が置かれている必要があります。JSB ルーチンはこのアラインメントを手助けします。)
インライン・オプションを使用して, 6 個または 8 個を超える引数を使用した呼び出しを,ローカルな JSB ルーチンを使用せずに行うことができます。ただし,その利用には制限があります ( 付録 E を参照)。
$PUSH_ARG64 マクロは,引数を正しい引数レジスタまたはスタック領域に直接移動します。これは実際にはスタックのプッシュではなく, 32 ビット呼び出しで使用する PUSHL 命令を模したものです。
$CALL64 マクロは,引数カウント・レジスタを設定し,対象ルーチンを呼び出します。 JSB ルーチンが作成されている場合は,そのルーチンを呼び出します。プッシュした引数の数が $SETUP_CALL64 で指定した数と一致しない場合,このルーチンはエラーを報告します。 $CALL64 と $PUSH_ARG64 は, $SETUP_CALL64 がすでに呼び出されていることを確認します。
$SETUP_CALL64,$PUSH_ARG64,および $CALL64 を使用する際には,以下の点に注意してください。
注意 マクロ $SETUP_CALL64,$PUSH_ARG64,および $CALL64 は,インライン・シーケンスで使用されることを意図しています。つまり $SETUP_CALL64/$PUSH_ARG64/$CALL64 シーケンスの途中に分岐したり, $PUSH_ARG64 マクロの前後で分岐したり, $CALL64 を呼び出さずにこのシーケンスから外に分岐することはできません。 |
$SETUP_CALL64,$PUSH_ARG64,および $CALL64 についての詳細は, 付録 E を参照してください。
5.2.2 可変サイズの引数リストを使用した呼び出し
可変サイズの引数リストを使用した呼び出しでは,以下の手順に示すように EVAX_CALLG_64 ビルトインを使用します。
EVAX_CALLG_64 (Rn), routine |
EVAX_CALLG_64 ビルトインの引数リストは,クォドワードの引数カウントから始まる一連のクォドワードとして読み込まれます。
.CALL_ENTRY のパラメータ QUAD_ARGS=TRUE を使用し,ルーチンの引数リスト中でのクォドワード引数の使用を宣言することができます。 QUAD_ARGS パラメータがあると,コンパイラは,引数リストに対するクォドワード参照があったときに異なる動作をします。まず,通常このような参照で必要となる引数リストのホーミングを適用しません。 (ホーミングは,その定義上,引数をロングワード・スロットにパックするため,クォドワード値が格納された引数リストはホーミングできません。) また,引数リストに対するクォドワード参照では,
アラインされていないメモリ参照は報告されません。
引数リスト参照自体に対して生成される実際のコードは, MOVQ のように VAX のクォドワード命令の中に参照がある場合を除いて, QUAD_ARGS 句があっても変わりません。たいていの場合,QUAD_ARGS は,クォドワード参照による引数リストのホーミングが行われないようにし,不要なアラインメント・メッセージを抑止するだけです。この抑止は,EVAX_ ビルトインと, MOVQ などの VAX のクォドワード命令の両方に適用されます。
VAX のクォドワード命令では, QUAD_ARGS 句を指定すると,EVAX_ ビルトインと同じように,クォドワード引数を実際のクォドワードとして読み込みます。次の例を考えます。
5.3 64 ビット引数の宣言
MOVQ 4(AP), 8(R2) |
QUAD_ARGS 句を指定すると,MOVQ は引数 1 の 64 ビット全体を 8(R2) の位置のクォドワードに格納します。 QUAD_ARGS 句が指定されていないと, MOVQ は引数 1 と 2 の下位ロングワードを 8(R2) の位置のクォドワードに格納します。
QUAD_ARGS は,AP ベースの遅延モードのオペランドに対して生成されるコードにも影響を与えます。実効アドレスをメモリ内の引数からロードする必要がある場合は, QUAD_ARGS が有効になっていると,ロングワードとしてではなくクォドワードとして読み込まれます。
QUAD_ARGS を使用する場合には以下の点に注意してください。
MACRO には,明示的なポインタ型宣言はありません。レジスタに 64 ビット・ポインタ値を作成する方法には,さまざまなものがあります。最も一般的な方法は,EVAX_LDQ ビルトインを使用して,メモリに格納されているアドレスをロードする方法と, MOVAx を使用して,特定のオペランドのアドレスを取得する方法です。
64 ビットのポインタ値をレジスタに格納したら,通常の命令で 64 ビット・アドレスにアクセスします。そのアドレスから読み込まれるデータの量は,使用する命令に依存します。次の例を考えます。
MOVL 4(R1), R0 |
MOVL 命令は,R1 に 32 ビットのポインタが格納されている場合でも, 64 ビットのポインタが格納されている場合でも, R1 からオフセット 4 の位置にあるロングワードを読み込みます。
しかし,特定のアドレッシング・モードでは,実効アドレスを計算するために,算術命令の生成が必要です。 VAX との互換性のため,コンパイラはこれらをロングワード演算として計算します。たとえば, 4 + <1@33>を計算すると,シフトした値が 32 ビットを超えるため,結果の値は 4 となります。クォドワード・モードが有効な場合は,上位ビットは失われません。
バージョン 7.0 よりも前の OpenVMS Alpha に添付されていたコンパイラでは, /ENABLE=QUADWORD 修飾子 (および対応する指示文.ENABLE QUADWORD と .DISABLE QUADWORD) は,定数式の評価が実行されるモードにだけ影響がありました。 OpenVMS Alpha Version 7.0 および OpenVMS I64 では,アドレス計算にも影響を与えるように拡張されました。その結果,SxADDQ や ADDQ などのクォドワード命令でアドレスが計算されるようになりました。
モジュール全体でクォドワード演算を使用するには,コマンド行で /ENABLE=QUADWORD を指定します。特定のセクションだけにクォドワード演算を適用する場合は,指示文 .ENABLE QUADWORD と .DISABLE QUADWORD を使用してこれらのセクションを囲みます。
MOVAL (R1)[R0], R2 |
R1 に値 7FFFFFFF が格納されており,R0 に 1 が格納されているとします。 MOVAL 命令は S4ADDL 命令を生成します。シフトと加算の結果 32 ビットを超えますが,格納される結果は符号拡張された下位 32 ビットです。
クォドワード演算を使用すると (S4ADDQ),次の例に示すように真のクォドワード値となります。
S4ADDL R0, R1, R2 => FFFFFFFF 80000003 S4ADDQ R0, R1, R2 => 00000000 80000003 |
ラップ動作の問題は,インデックス・モードのアドレッシングだけに限りません。次の例を考えます。
MOVAB offset(R1), R0 |
シンボル offset がコンパイル時に定数でない場合は,この命令によって値がリンケージ・セクションから読み込まれ, R1 の値に加算されます (ADDL 命令を使用)。これを ADDQ に変更すると,値が 32 ビットを超えている場合に結果が変わります。
Itanium アーキテクチャには S4ADDL 命令に相当する命令がありませんが,コンパイラは shladd 命令と sxt4 命令を生成し,この効果をシミュレートします。
目次 | 索引 |
|