前へ | 次へ | 目次 | 索引 |
可変サイズ引数リストでの呼び出しの場合,次の手順にしたがって新しい EVAX_CALLG_64 ビルトインを使用します。
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 を使用する場合は,次の点に注意してください。
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 も使用しなければなりません。システム上に最新バージョンがインストールされ,論理名が正しいディレクトリを示していることを確認してください。
ここでは 64 ビット・アドレスの操作,64 ビット値の下位 32 ビットの符号拡張のチェック,および 64 ビット形式のディスクリプタをチェックする C マクロについて説明します。
64 ビット文字列ディスクリプタを構成します。
$DESCRIPTOR64 name, string
name:変数の名前。
string:文字列のアドレス。例:
int status; $DESCRIPTOR64 (gblsec, "GBLSEC_NAME"); ... /* Create global page file section */ status = sys$create_gpfile (&gblsec, 0, 0, section_size, 0, 0); ...
このマクロは,SYS$LIBRARY:DECC$RTLDEF.TLB 内の descrip.h にあります。
64 ビット・ディスクリプタを識別します。
$is_desc64 desc
desc: 32 ビットまたは 64 ビット・ディスクリプタのアドレス。戻り値:
ディスクリプタが 32 ビット・ディスクリプタの場合は0。
ディスクリプタが 64 ビット・ディスクリプタの場合は1。例:
#include <descrip.h> #include <far_pointers.h> ... if ($is_desc64 (user_desc)) { /* Get 64-bit address and 64-bit length from descriptor */ ... } else { /* Get 32-bit address and 16-bit length from descriptor */ ... }
このマクロは,SYS$LIBRARY:DECC$RTLDEF.TLB 内の descrip.h にあります。
クォドワードが 32 ビット符号拡張されているかどうかをチェックします。
$is_32bits arg
入力: arg 64 ビット値。
出力:
arg が 32 ビット符号拡張されている場合は1。
arg が 32 ビット符号拡張されていない場合は0。例:
#include <starlet_bigpage.h> ... if ($is_32bits(user_va)) counter_32++; /* Count number of 32-bit references */ else counter_64++; /* Count number of 64-bit references */
このマクロは,SYS$LIBRARY:SYS$STARLET_C.TLB 内の starlet_bigpage.h にあります。
前へ | 次へ | 目次 | 索引 |