日本-日本語 |
|
|
|
OpenVMS マニュアル |
|
HP OpenVMS MACRO コンパイラ
|
目次 | 索引 |
付録 D
VAX から Alpha または I64 への移植用のマクロ
この付録では,VAX MACRO コードを OpenVMS Alpha システムまたは OpenVMS I64 システムに移植する際に役立つマクロについて説明します。マクロは,機能ごとに以下のグループに分類されています。
この付録で説明するマクロでは,レジスタ・セットを示す引数を使用できます。レジスタ・セットを表現するには,次の例のようにレジスタをコンマで区切り,山括弧で囲みます。
<R1,R2,R3> |
レジスタ・セットにレジスタが 1 つしか含まれない場合は,次のように山括弧を省略します。
R1 |
以下のマクロは,ページ・サイズに依存する値を計算するための,標準的でアーキテクチャに依存しない方法を提供します。
これらのマクロはディレクトリ SYS$LIBRARY:STARLET.MLB にあり,アプリケーション・コードとシステム・コードの両方で使用できます。アプリケーション・コードは SYSTEM_DATA_CELLS にアクセスできないため,適切なマスク,シフト値などを指定する必要があります。
シフト値はプロセッサのページ・サイズと関係があります。 表 D-1 に示すように, rightshift 値は負で,leftshift 値は正です。
ページ・サイズ | rightshift | leftshift |
---|---|---|
512 バイト (VAX) | -9 | 9 |
8K (OpenVMS Alpha または OpenVMS I64 ) | -13 | 13 |
16K 1 | -14 | 14 |
32K 1 | -15 | 15 |
64K 1 | -16 | 16 |
通常,アプリケーションは $GETSYI (アイテム記述子 SYI$_PAGESIZE を指定) を呼び出して CPU 固有のページ・サイズを取得し,それを元にその他の値を計算します。
以下の規則がこの項で説明するマクロに適用されます。
$BYTES_TO_PAGES |
バイト数をページ数に変換します。
$BYTES_TO_PAGES source_bytcnt, dest_pagcnt, rightshift, roundup=YES, quad=YES
source_bytcnt
ソースバイト数です。dest_pagcnt
ページ数の格納先です。rightshift
アプリケーション指定のシフト値のアドレスです (かけ算の代わり)。この値は, 表 D-1 に示すように,ページ・サイズの関数となっています。roundup=YES
YES の場合,シフトの前に「ページ・サイズ--1」がバイト数に加算されます。 NO の場合,ページ数は切り捨てられます。その他の値は,「ページ・サイズ--1」の値を指すユーザ指定のアドレスとして扱われます。 roundup=YES は, rightshift 引数と一緒に指定できない点に注意してください。両方の引数を指定してマクロを実行すると,コンパイル時に警告が出力されます。quad=YES
YES の場合,変換で 64 ビット・アドレッシングがサポートされます。 NO の場合,変換で 64 ビット・アドレッシングがサポートされません。
$NEXT_PAGE |
次のページの先頭バイトの仮想アドレスを計算します。
$NEXT_PAGE source_va, dest_va, clearbwp=NO, user_pagesize_addr, user_mask_addr, quad=YES
source_va
ソース仮想アドレスです。dest_va
次のページの仮想アドレスの格納先です。clearbwp=NO
YES の場合,ソース仮想アドレスのページ内のバイトの部分をマスクします。 clearbwp=NO オプションを指定すると,ページ境界を指定していることが分かっている場合や,ページ・サイズで除算しようとしている場合に不要な命令が実行されなくなり,性能が向上します。user_pagesize_addr
アプリケーション・データ領域にあるページ・サイズ値のアドレスです (アイテム記述子 SYI$_PAGESIZE を指定して $GETSYI システム・サービスを呼び出すことで返されます)。この引数を省略した場合,マクロは MMG$GL_PAGESIZE (bigpage) または MMG$C_VAX_PAGE_SIZE (vaxpage) を使用します。user_mask_addr
アプリケーションが用意するページ内バイトのマスクのアドレスです。この引数を省略した場合, user_pagesize_addr も省略した場合は MMG$GL_BWP_MASK が使用され,そうでない場合は user_pagesize_addr の内容から 1 を引き,その値が使用されます。quad=YES
YES の場合,変換で 64 ビット・アドレッシングがサポートされます。 NO の場合,変換で 64 ビット・アドレッシングがサポートされません。
$PAGES_TO_BYTES |
ページ数をバイト数に変換します。
$PAGES_TO_BYTES source_pagcnt, dest_bytcnt, leftshift, quad=YES
source_pagcnt
ソース・ページ数です。dest_bytcnt
バイト数の格納先です。leftshift
アプリケーション指定のシフト値のアドレスです (かけ算の代わり)。この値は, 表 D-1 に示すように,ページ・サイズの関数となっています。quad=YES
YES の場合,変換で 64 ビット・アドレッシングがサポートされます。 NO の場合,変換で 64 ビット・アドレッシングがサポートされません。
$PREVIOUS_PAGE |
前のページの先頭バイトの仮想アドレスを計算します。
$PREVIOUS_PAGE source_va, dest_va, clearbwp=NO, user_pagesize_addr, user_mask_addr, quad=YES
source_va
ソース仮想アドレスです。dest_va
前のページの仮想アドレスの格納先です。clearbwp=NO
YES の場合,ソース仮想アドレスのページ内のバイトの部分をマスクします。 clearbwp=NO オプションを指定すると,ページ境界を指定していることが分かっている場合や,ページ・サイズで除算しようとしている場合に不要な命令が実行されなくなり,性能が向上します。user_pagesize_addr
アプリケーション・データ領域にあるページ・サイズ値のアドレスです (アイテム記述子 SYI$_PAGESIZE を指定して $GETSYI システム・サービスを呼び出すことで返されます)。この引数を省略した場合,マクロは MMG$GL_PAGESIZE (bigpage) または MMG$C_VAX_PAGE_SIZE (vaxpage) を使用します。user_mask_addr
アプリケーションが用意するページ内バイトのマスクのアドレスです。この引数を省略した場合, user_pagesize_addr も省略した場合は MMG$GL_BWP_MASK が使用され,そうでない場合は user_pagesize_addr の内容から 1 を引き,その値が使用されます。quad=YES
YES の場合,変換で 64 ビット・アドレッシングがサポートされます。 NO の場合,変換で 64 ビット・アドレッシングがサポートされません。
$ROUND_RETADR |
メモリ管理サービスから返された retadr 配列内の仮想アドレスが示す範囲を,CPU 固有のページに基づく範囲に丸めます。戻り値は,それ以降の別のメモリ管理システム・サービスの呼び出しで, inadr 配列として指定できます。
$ROUND_RETADR retadr, full_range, user_mask_addr, direction=ASCENDING
retadr
2 つの 32 ビット・アドレスからなる配列のアドレスです。通常,$CRMPSC またはそれに似たサービスから返されます。この値の形式は,"label" または "(Rx)" です。full_range
2 つのロングワードからなる出力配列。 FULL_RANGE[0] は,retadr[0] を CPU固有のページ境界に丸めたもの (切り捨て) で, FULL_RANGE[1] は,retadr[1] を CPU 固有のページ境界に切り上げ, 1 を引いたもの (つまり,ページ内の最後のバイト) です。user_mask_addr
アプリケーションが用意するページ内バイトのマスクのアドレスです。この引数を省略した場合, OpenVMS Alpha システムまたは OpenVMS I64 システムでは MMG$GL_BWP_MASK が使用され, OpenVMS VAX システムでは VA$M_BYTE が使用されます。direction=ASCENDING
丸めの方向です。キーワードを次の表に示します。
ASCENDING retadr[0] < retadr[1] DESCENDING retadr[1] < retadr[0] UNKNOWN 値は実行時に比較され,正しく丸められる。
$START_OF_PAGE |
仮想アドレスを,ページ内の先頭バイトのアドレスに変換します。
$START_OF_PAGE source_va, dest_va, user_mask_addr, quad=YES
source_va
ソース仮想アドレスです。dest_va
ページ内の先頭バイトの仮想アドレスの格納先です。user_mask_addr
アプリケーションが用意するページ内バイトのマスクのアドレスです。この引数を省略した場合, OpenVMS Alpha システムまたは OpenVMS I64 システムでは MMG$GL_BWP_MASK が使用され, OpenVMS VAX システムでは MMG$C_VAX_PAGE_SIZE - 1 ($pagedef で定義) が使用されます。quad=YES
YES の場合,変換で 64 ビット・アドレッシングがサポートされます。 NO の場合,変換で 64 ビット・アドレッシングがサポートされません。
D.2 64 ビット・レジスタの保存と復元 |
VAX MACRO ソース・コードでレジスタ値を保存して復元しなければならないことがよくあります。その理由としては,この処理がインタフェースの一部として定義されていることや,コードが作業レジスタを必要とすることが考えられます。
OpenVMS VAX では,コード上で任意の数のマクロを呼び出してこの処理を行えます。 OpenVMS Alpha と OpenVMS I64 では,これらのマクロを,スタックに対する 64 ビット版のプッシュとポップに単純に置き換えることはできません。マクロの呼び出し元が,クォドワード境界にアラインされたスタックを持っているとは限らないためです。代わりに,このようなマクロを $PUSH64 マクロと $POP64 マクロで置き換えます。これらのマクロは STARLET.MLB にあり,レジスタの 64 ビット値全体を保存/復元しますが,ロングワード参照を使用してこの処理を実行します。
$POP64 |
スタックの先頭の 64 ビット値をレジスタにポップします。
$POP64 reg
reg
スタックの先頭から取り出した 64 ビット値を格納するレジスタです。
$POP64 は,スタックの先頭にある 64 ビット値を取り出し,ロングワード命令を使用してレジスタに格納します。これは,アラインメント・フォルトを避けなければならない場合で,しかも 64 ビット全体を復元する必要がある場合に,クォドワード命令の使用を避けるために使用します。
$PUSH64 |
64 ビット・レジスタの内容をスタックにプッシュします。
$PUSH64 reg
reg
スタックにプッシュするレジスタです。
$PUSH64 は 64 ビット・レジスタを受け取り,ロングワード命令を使用してスタックに格納します。これは,アラインメント・フォルトを避けなければならない場合で,しかも 64 ビット全体を格納する必要がある場合に,クォドワード命令の使用を避けるために使用します。
D.3 ワーキング・セットへのページのロック |
ワーキング・セットにページをロックするために, 5 つのマクロが提供されています。これらのマクロは SYS$LIBRARY:LIB.MLB にあります。これらのマクロの使用方法については, 第 3.10 節 を参照してください。
3 つのマクロは,イメージ初期化時のロックダウンで使用し, 2 つのマクロは,オンザフライのロックダウンで使用します。
注意 IPL を,ページ・フォルトが発生しない 2 よりも上げることでコードをロックする場合は,その範囲内のコードが実行時ライブラリやその他のプロシージャを呼び出さないことを確認してください。 VAX MACRO コンパイラは,特定の VAX 命令をエミュレートするためのルーチンの呼び出しを生成します。これらのマクロを使用するイメージは,これらのルーチンの参照がページング不可のエグゼクティブ・イメージ内のコードで解決されるように,システム・ベース・イメージとリンクする必要があります。 OpenVMS I64 システムでは,これらのマクロはまだ開発中であり,ワーキング・セットをロックするための追加の OpenVMS ルーチンが提供されます。詳細は, OpenVMS V8.2 リリース・ノート[翻訳版] を参照してください。 |
D.3.1 イメージ初期化時のロックダウン |
以下のマクロは,イメージ初期化時のロックダウンで使用します。
$LOCK_PAGE_INIT |
$LOCKED_PAGE_START と $LOCKED_PAGE_END を使用して初期化時にロックする領域を線引きするイメージの初期化ルーチンで使用する必要があります。
$LOCK_PAGE_INIT [error]
[error]
いずれかの $LKWSET 呼び出しが失敗した場合に分岐する分岐先アドレスです。このアドレスに到達した場合,R0 には失敗した呼び出しの状態が設定されます。 R1 には,コードをロックするための呼び出しに失敗した場合は 0,その呼び出しは成功したものの,リンケージ・セクションをロックするための呼び出しが失敗した場合は 1 が設定されます。
$LOCK_PAGE_INIT は,必要な psect を作成し, $LWKSET を呼び出して, $LOCKED_PAGE_START と $LOCKED_PAGE_END で定義されたコード・セクションとリンケージ・セクションを,ワーキング・セット内にロックします。 R0 と R1 の内容は,このマクロによって壊れます。このマクロでロックされる psect は $LOCK_PAGE_2 と $LOCK_LINKAGE_2 です。他の言語で記述された他のモジュールのコード・セクションでこれらの psect を使用している場合は, VAX MACRO モジュール内でこのマクロを呼び出すことでロックされます。
$LOCKED_PAGE_END |
イメージの初期化時に $LOCK_PAGE_INIT マクロによってロックされるコード・セクションの終わりをマークします。
$LOCKED_PAGE_END [link_sect]
[link_sect]
$LOCKED_PAGE_START マクロを実行したときの実際のリンケージ psect がデフォルトのリンケージ psect $LINKAGE でなかった場合に戻る psect です。
$LOCKED_PAGE_END は $LOCKED_PAGE_START とともに使用され,イメージの初期化時に $LOCK_PAGE_INIT マクロによって初期化されるコードを線引きします。これらのマクロで線引きされたコードには,ルーチン全体が含まれている必要があります。実行がいずれかのマクロを超えたり,ロックされたコードから外に分岐したり,外からロックされたコードの中に分岐することはできません。ロックされたコード・セクションの中に分岐した場合や,ロックされたコード・セクションから外に分岐しようとした場合,またはマクロを超えて実行しようとした場合は,コンパイラによってエラーが出力されます。
目次 | 索引 |
|