[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]

12 MACRO-32プログラミングの 64ビット・アドレッシング・サポート

本章では,MACRO-32コンパイラおよび関連コンポーネントによる 64ビット・アドレッシング・サポートについて説明します。 主に引数の受け渡しとアドレス計算に対して変更が行われています。


12.1 64ビット・アドレッシングのガイドライン

OpenVMS Alpha用にコンパイルされるVAX MACROコード内での, 64ビット・アドレッシングの使用に関するガイドラインを次に示します。


12.2 64ビット・アドレッシングのための新規コンポーネントおよび変更されたコンポーネント

MACRO-32プログラミングでの64ビット・アドレッシング・サポートを提供する, 新規コンポーネントおよび変更されたコンポーネントの一覧を 表 12-1に示します。

表 12-1 64ビット・アドレッシングのための新規コンポーネントおよび変更されたコンポーネント

コンポーネント 説明
$SETUP_CALL64 呼び出しシーケンスを初期化する新規マクロ
$PUSH_ARG64 引数プッシュに相当する処理を行う新規マクロ
$CALL64 ターゲット・ルーチンを起動する新規マクロ
$IS_32BITS 64ビット値の下位32ビットの符合拡張をチェックする新規マクロ
$IS_DESC64 ディスクリプタが64ビット形式ディスクリプタか決定する新規マクロ
QUAD=NO/YES 64ビット仮想アドレスをサポートするためのページ・マクロの新規パラメータ
/ENABLE=QUADWORD QUADWORDパラメータは拡張され,64ビット・アドレス計算を含む
.CALL_ENTRY QUAD_
ARGS=TRUE|FALSE
QUAD_ARGS=TRUE|FALSEは引数リストへのクォドワード参照を指定する新規パラメータ
.ENABLE QUADWORD
/.DISABLE QUADWORD
QUADWORDパラメータは拡張され,64ビット・アドレス計算を含む
EVAX_SEXTL 64ビット値の下位32ビットを, ターゲットに対して符合拡張する新規ビルトイン
EVAX_CALLG_64 可変サイズの引数リストで 64ビット呼び出しをサポートするため新規ビルトイン
$RAB64および$RAB64_STORE 64ビット・アドレス空間でバッガを使用するための新規RMSマクロ


12.3 64ビット値の引き渡し

64ビット値を渡す方法は,引数リストのサイズが固定, または可変であるかどうかによって異なります。次の節では, これらの方法について説明します。


12.3.1 固定長サイズ引数リストでの呼び出し

固定サイズ・リストでの呼び出しの場合, 表 12-2の手順に従って新規マクロを使用します。

表 12-2 固定サイズ引数リストでの 64ビット値の引き渡し

手順 使用するマクロ
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を使用する前に必要です。引数の個数が6個を越える場合, このマクロはローカルJSBルーチンを作成し,これが起動されて呼び出しを実行します。 引数の個数が6個以下の場合,引数のロードと呼び出しはインラインで行われ, きわめて効率的です。なお,$SETUP_CALL64に指定される引数の個数には, #が含まれないことに注意してください。(これは,標準呼び出しシーケンスが, オクタワード・アライン・スタックの先頭のスタック引数の, オクタワード・アラインを求めるためです。JSBルーチンは, このアライン操作を行います。)

インライン・オプションを使用すると,ローカルJSBルーチンがなくても, 6個を越える引数を指定して呼び出しを強制的に実行できます。ただし, その使用には制限があります(詳細は 付録 Bを参照してください)。

$PUSH_ARG64マクロは,引数を正しい引数レジスタやスタック位置に直接移動します。 これは実際にはスタック・プッシュではありませんが, 32ビット呼び出しの中で使用されるPUSHL命令に似ています。

$CALL64マクロは引数カウント・レジスタを設定し,ターゲット・ルーチンを起動します。 JSBルーチンが作成された場合は,そのルーチンを終了させます。 プッシュされた引数の個数が, $SETUP_CALL64で指定された個数に一致しない場合, エラーが報告されます。 $CALL64および$PUSH_ARG64を使用する前に, $SETUP_CALL64が起動されていることを確認してください。


12.3.1.1 $SETUP_CALL64,$PUSH_ARG64,および $CALL64の使用上の注意

$SETUP_CALL64,$PUSH_ARG64,$CALL64を使用するときは,次の点に注意してください。

注意
$SETUP_CALL64,$PUSH_ARG64,および$CALL64マクロは, インライン・シーケンスで使用することを目的としています。つまり, $SETUP_CALL64/$PUSH_ARG64/$CALL64シーケンスの中央に分岐したり, $PUSH_ARG64マクロの回りで分岐することはできず,シーケンスを出て $CALL64を避けることもできません。

$SETUP_CALL64,$PUSH_ARG64,および$CALL64についての詳細は, 付録 Bを参照してください。


12.3.2 可変サイズ引数リストでの呼び出し

可変サイズ引数リストでの呼び出しの場合,次の手順にしたがって新しい EVAX_CALLG_64ビルトインを使用します。

  1. メモリ内引数リストを作成する。

  2. メモリ内引数リストを渡し,ルーチンを呼び出す。次の例を参照。
         EVAX_CALLG_64 (Rn), routine
    
EVAX_CALLG_64ビルトイン中の引数リストは,クォドワード引数の個数を先頭に, 一連のクォドワードとして読み込まれます。


12.4 64ビット引数の宣言

.CALL_ENTRYの新パラメータ,QUAD_ARGS=TRUEを使用すると, ルーチンの引数リスト内でのクォドワード引数の使用を宣言できます。 QUAD_ARGSパラメータが指定されている場合,引数へのクォドワード参照が発生すると, コンパイラは通常とは異なる動作をします。まず,このような参照が通常要求する, 引数リスト・ホーミングが強制されません。( クォドワード値を含んでいる引数はホーミングできません。これは,定義により, ホーミングが引数をロングワード・スロットにパックするためです。)第2に, 非アライン・メモリ参照が,引数リストへのクォドワード参照で報告されません。

引数リスト参照用に生成された実際のコードは, QUAD_ARGS句の指定によって変更を受けることはありません。ただし,MOVQなど VAXクォドワード命令の中で参照が行われる場合は除きます。多くの場合, QUAD_ARGSは,クォドワード参照に基づいて引数リストのホーミングを禁止し, 不要なアライメント・メッセージの表示を抑制します。この表示の抑制は, EVAX_ビルトインと,MOVQなどのVAXクォドワード命令の両方に適用されます。

VAXクォドワード命令の場合,QUAD_ARGS句は, EVAX_ビルトインの場合と同じように, 実際のクォドワードとして, クォドワード引数の読み込みをコンパイラに対して指定します。次の例を考えます。

     MOVQ    4(AP), 8(R2)
QUAD_ARGS句が指定されている場合,MOVQは,引数1の64ビット全体を,8(R2) のクォドワードに格納します。QUAD_ARGS句が指定されていない場合,MOVQは, 引数1および2の下位ロングワードを,8(R2)のクォドワードに格納します。

QUAD_ARGSもAPに基づいた defferdモード・オペランドのために生成されたコードに影響を与えます。 メモリ中の引数から有効なアドレスをロードしなければならない場合に, QUAD_ARGSが有効であれば, これはロングワードではなくクォドワードとして読み込まれます。


12.4.1 QUAD_ARGSの使用上の注意

QUAD_ARGSを使用する場合は,次の点に注意してください。


12.5 64ビット・アドレス計算の指定

MACRO-32に明示的なポインタの型宣言はありません。64ビット・ポインタ値は, 各種の方法でレジスタに作成できます。もっとも一般的な方法は, メモリに保存されているアドレスをEVAX_LDQビルトインでロードし, 指定されたオペランドのアドレスをMOVAxで取得する方法です。

レジスタに64ビット・ポインタ値を作成したら,通常の命令で 64ビット・アドレスにアクセスします。そのアドレスから読み込まれるデータの量は, 使用される命令によってそれぞれ異なります。次の例を考えます。

     MOVL     4(R1), R0
R1が含むポインタが32ビットの場合も64ビットの場合も,MOVL命令は R1からのオフセットが4の位置でロングワードを読み込みます。

しかし,特定のアドレッシング・モードでは,算術命令を生成して, 有効なアドレスを計算することを要求します。VAXとの互換性を目的として, コンパイラはこれらをロングワード操作として計算します。たとえば, 4 +<1@33> の結果は,シフトされた値が32ビットを越えるため, 値4となります。クォドワード・モードが有効の場合, 上位ビットが失われることはありません。

以前のバージョンのOpenVMS Alphaと共に出荷されていたコンパイラの場合, /ENABLE=QUADWORD修飾子(および対応する.ENABLE QUADWORDディレクティブと .DISABLE QUADWORDディレクティブ)は, 定数式の評価が行われるモードに影響するだけでした。OpenVMS Alpha Version 7.0 の場合,これらは拡張され,アドレス計算に影響します。この結果, SxADDQおよびADDQなどのクォドワード命令でアドレスが計算されます。

モジュール全体でクォドワード操作を使用するには,コマンド行で /ENABLE=QUADWORDを指定します。 特定のセクションにだけクォドワード操作を適用するには,該当するセクションを .ENABLE QUADWORDおよび .DISABLE QUADWORDディレクティブで囲みます。

/ENABLE=QUADWORDを使用しても,性能が低下することはありません。


12.5.1 ロングワード操作の折り返し動作への影響

コンパイラは, クォドワード計算を使用してすべてのアドレッシング計算を行うことはできません。 これは,既存のコードは32ビット操作の折り返し動作に依存するためです。つまり, コードは,実際には 32ビットをオーバフローするアドレッシング操作を実行する場合もあり, このとき上位ビットは廃棄されます。クォドワード・モードでの計算は, 互換性がありません。

/ENABLEを使用してモジュール全体に対してクォドワード評価を設定する前に, 既存のコードをチェックして,ロングワードの折り返しへの影響を確認してください。 これを簡単に行うことはできませんが, プログラミング手法としてこれはきわめて珍しいもので, コードの外側で呼び出されている可能性もあります。

次の例は折り返しの問題を示しています。

     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
シンボル・オフセットがコンパイル時定数でない場合,この命令によって, 値はリンケージ・セクションから読み込まれ,(ADDL命令を使用して) R1内の値に追加されます。これをADDQに変更すると,値が 32ビットを越える場合に結果が変化する可能性があります。


12.6 符合拡張およびチェック

新しいビルトインのEVAX_SEXTL (符号拡張ロングワード)は,64ビット値の下位 32ビットをデスティネーションに対して符号拡張します。このビルトインは, デスティネーションに対して, ソースの下位ロングワードの符号拡張を明示的に行うものです。

EVAX_SEXTLは64ビット値の下位32ビットを取り,上位32ビットを符号拡張 (値のビット31の内容)で埋め,64ビットの結果をデスティネーションに書き込みます。

次の例は,すべて正しい使用例です。

     evax_sextl r1,r2
     evax_sextl r1,(r2)
     evax_sextl (r2), (r3)[r4]
これらの例に示すように,オペランドは必ずしもレジスタでなくても構いません。

新規マクロ$IS_32BITSを使用すると, 64ビット値の下位 32ビットの符合拡張をチェックすることができます。詳細は 付録 Bを参照してください。


12.7 Alpha命令ビルトイン

コンパイラは,多くのAlpha命令をビルトインとしてサポートします。 (OpenVMS Alphaと共に最初に出荷されたコンパイラ以来利用できる) これらのビルトインの多くは,64ビットを操作できます。 各ビルトインの関数およびその有効なオペランドについては, 『Porting VAX MACRO Code to OpenVMS Alpha』を参照してください。また,各 Alpha命令についての詳細は,『MACRO-64 Assembler for OpenVMS AXP Systems Reference Manual』を参照してください。


12.8 ページ・サイズ依存値の計算

64ビット仮想アドレスをサポートする新しい修飾子QUAD=NO/YESは, 次に示す各ページ・マクロで使用できます。 これらのマクロは,標準の,アーキテクチャに依存しない手段を提供して, ページ・サイズ依存値を計算します。これらのマクロについての詳細は, 『Porting VAX MACRO Code to OpenVMS Alpha』を参照してください。


12.9 64ビット・アドレス空間でのバッガの作成および使用

64ビット・アドレス空間でのバッファの作成および使用を目的として,$RABおよび $RAB_STORE制御ブロック・マクロが拡張されました。64ビット・バージョンは, それぞれ$RAB64および$RAB64_STOREです。現時点では,残りのRMSインタフェースは 32ビットに制限されています。$RAB64および$RAB64_STOREについての詳細は, 第5章を参照してください。


12.10 64Kバイトを越える転送のコーディング

MOVC3およびMOVC5 MACRO-32命令は,64ビット・アドレスを正しく処理しますが, 転送は64Kバイト長に限られます。この制限が適用されるのは,MOVC3と MOVC5がワード・サイズ長を受け取ることが原因です。

64Kバイトを越える転送については,OTS$MOVE3およびOTS$MOVE5を使用します。 OTS$MOVE3およびOTS$MOVE5は,ロングワード・サイズ長を受け取ります (LIB$MOVC3およびLIB$MOVC5は,MOVC3およびMOVC5と同じ 64Kバイト長の制限を受けます)。次の例では,MOVC3をOTS$MOVE3で置換します。

MOVC3を使用するコード

     MOVC3      BUF$W_LENGTH(R5), (R6), OUTPUT(R7)   ; Old code, word length
ロングワード長を伴う同じ内容の64ビット・コード
     $SETUP_CALL64  3              ; Specify three arguments in call
     EVAX_ADDQ      R7, #OUTPUT, R7
     $PUSH_ARG64    R7             ; Push destination, arg #3
     $PUSH_ARG64    R6             ; Push source, arg #2
     MOVL           BUF$L_LENGTH(R5), R16
     $PUSH_ARG64    R16            ; Push length, arg #1
     $CALL64        OTS$MOVE3

     MOVL           BUF$L_LENGTH(R5), R16
     EVAX_ADDQ      R6, R16, R1    ; MOVC3 returns address past source
     EVAX_ADDQ      R7, R16, R3    ; MOVC3 returns address past destination

MOVC3はR0,R2,R4およびR5をクリアするので, その内容がもはや必要ないことを確認してください。

OTS$MOVE3およびOTS$MOVE5は,『OpenVMS RTL General Purpose (OTS$) Manual』 の中でほかのLIBOTSルーチンと共に説明されています。


12.11 MACRO-32コンパイラの使用

OpenVMS Alpha 64ビット・アドレッシング機能を使用するには,OpenVMS Alphaバージョン7.0に含まれているMACRO-32コンパイラを使用しなければなりません。

最新バージョンのコンパイラを使用する場合, 64ビット・アドレッシング機能を使用しているかどうかに関わらず, 最新バージョンのALPHA$LIBRARY:STARLET.MLBも使用しなければなりません。 システム上に最新バージョンがインストールされ, 論理名が正しいディレクトリを示していることを確認してください。


[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]