日本-日本語
日本HPホーム 製品 & サービス OpenVMS製品情報
≫  お問い合わせ


OpenVMS マニュアル


 

OpenVMS ドキュメント
ライブラリ

タイトルページ
目次
まえがき
第 1 部 : 概念と方法
第 1 章:Macro-32コードの移植の準備
第 2 章:MACROコンパイラのプラットフォームごとの動作
第 3 章:ソースに対する推奨される変更と必要な変更
第 4 章:移植したコードの性能改善
第 5 章:MACROの64ビット・アドレッシングのサポート
第 2 部:リファレンス・セクション
付録 A :MACROコンパイラの修飾子
付録 B :専用の指示文
付録 C :MACROコンパイラ・ビルトイン
付録 D :VAXからAlphaまたはI64への移植用のマクロ
付録 E :64ビット・アドレッシング用のマクロ
索引
PDF
OpenVMS ホーム
HP OpenVMS MACRO コンパイラポーティングおよびユーザーズ・ガイド

HP OpenVMS MACRO コンパイラ
ポーティングおよびユーザーズ・ガイド


目次 索引



パック 10 進数指示文 .PACKED と,EDITPC 以外のすべてのパック 10 進数命令は,コンパイルされたモジュールの外部にあるエミュレーション・ルーチンによって, MACRO コンパイラでサポートされます。

2.9.1 OpenVMS VAX と OpenVMS Alpha / I64 の実装の違い

OpenVMS VAX システムと OpenVMS Alpha / I64 システムの実装の違いを以下のリストに示します。

  • パック 10 進数命令と不可分性
    パック 10 進数命令はすべてサブルーチン呼び出しによってエミュレートされるため,不可分でも再実行可能でもありません。また,.PRESERVE ATOMICITY 指示文や /PRESERVE=ATOMICITY オプションを使用して不可分にすることもできません。さらに OpenVMS Alpha システムや OpenVMS I64 システムでは,レジスタ R16 〜 R28 が命令の前後で保護されるという保証もありません。

  • 引数レジスタの使用
    引数は,引数レジスタ ( OpenVMS Alpha システムでは R16 〜 R21) によってエミュレーション・ルーチンに渡されます。パック 10 進数命令でこれらのレジスタを引数として使用すると,正常に動作しません。
    コンパイラは,VAX の引数ポインタ (AP) への参照を, OpenVMS Alpha の引数レジスタへの参照に変換します (2.3 項を参照)。たとえば,コンパイラは 4(AP) などの VAX の AP 相対のパラメータ参照を, Alpha の R16 に変換します。
    OpenVMS I64 システムでは,最初のパラメータはレジスタ R16 〜 R21 ではなく,レジスタ R32 〜 R39 で渡されます。そのため,引数レジスタは 6 個ではなく 8 個あります。また, OpenVMS I64 では, MACRO コンパイラはこれらのレジスタを名前で参照する手段を提供していません。そのため,これらのレジスタの使用が競合するようなコードを記述する可能性はありません。
    OpenVMS Alpha システムでは,パック 10 進数命令を使用する場合の AP ベースの参照の問題を防ぐには,これらの参照を含むルーチンのエントリ・ポイントで /HOME_ARGS=TRUE を指定するのが最も簡単です。これにより,すべての AP ベースの参照が,引数レジスタではなくプロシージャ・フレームから読み込まれるため,命令を変更する必要がありません。
    /HOME_ARGS=TRUE を使用しないと, AP レジスタ・ベースのパラメータ参照をパック 10 進数命令のオペランドとして含むソース・コードは,変更する必要があります。まず AP ベースのオペランドを一時レジスタにコピーし,パック 10 進数命令ではその一時レジスタを使用します。たとえば,次のコードがあるとします。

    MOVP     R0,  @8(AP), @4(AP) 
    


    これを次のように変更します。

    MOVL    8(AP), R1 
    MOVL    4(AP), R2 
    MOVP    R0,(R1),(R2) 
    


    OpenVMS I64 システムでは,入力引数レジスタは出力引数レジスタとは分離されていることに注意してください。

  • オーバフロー・トラップ
    VAX のプログラム状態ワード (PSW) のビット 7 とビット 5 は,それぞれ DV (10 進オーバフロー・トラップ有効) ビットと IV (整数オーバフロー・トラップ有効) ビットです。これらのビットは, VAX PSW のエミュレーションの一環としてはエミュレートされず,パック 10 進数のサポートにより整数と 10 進数のオーバフローを有効または無効にできます。ただし,コンパイル時に静的に行う必要があります。
    10 進オーバフロー・フォルトを有効にするには,シンボル PD_DEC_OVF をゼロ以外として定義します。 PD_DEC_OVF が定義されていないかゼロが設定されている場合は,パック 10 進数エミュレーション・ルーチンは 10 進数オーバフロー・フォルトを生成しません。整数オーバフロー・フォルトを有効にするには,シンボル PD_INT_OVF をゼロ以外として定義します。 PD_INT_OVF が定義されていないかゼロが設定されている場合は,パック 10 進数エミュレーション・ルーチンは整数オーバフロー・フォルトを生成しません。
    MACRO の修飾子 /ENABLE=OVERFLOW と指示文 .ENABLE OVERFLOW は,パック 10 進数エミュレーション・ルーチンのオーバフロー・トラップの有効化には関係しません。 PD_DEC_OVF と PD_INT_OVF を使用する必要があります。

  • 予約オペランド,10 進数のゼロ除算,整数オーバフロー, 10 進数オーバフローのトラップ・ルーチン
    エミュレーション・ルーチンには,予約オペランド, 10 進数のゼロ除算,整数オーバフロー, 10 進数オーバフローに対して固有のトラップ・ルーチンがあります。予約オペランドと 10 進数のゼロ除算のトラップは,事象が発生すると必ず取得されます。オーバフロー・トラップは,明示的に有効にされた場合にだけ取得されます。トラップ・ルーチンは,重大度を回復不可能として LIB$SIGNAL を呼び出します。

  • パック 10 進数エミュレーション・ルーチンからのメッセージ
    コンパイラのパック 10 進数エミュレーション・ルーチンからのすべてのメッセージでは,標準の OpenVMS シグナル値 SS$_ROPRAND, SS$_DECOVF,SS$_INTOVF,および SS$_FLTDIV が使用されます。

  • 引数の形式についての制限事項
    これらの命令はマクロで実装されているため,引数の形式に 1 つの制限があります。マクロの呼び出しでは,先頭にサーカンフレックス (^) があると,パラメータが文字列であることを意味するものと解釈され,サーカンフレックスの直後の文字は文字列の区切り文字と解釈されます。そのため, ^x20(SP) のようにオペランド型の指定で始まる引数は使用できません。 #^XFF などのイミディエイト・モード引数は,先頭の文字がサーカンフレックスでないため,オペランド型指定を使用できます。



2.10 浮動小数点命令の使用

POLYx,EMODx,およびすべての H_floating 命令を除くすべての浮動小数点命令と指示文がサポートされています。

これらの命令は,サブルーチン呼び出しによってエミュレートされます。このサポートは,既存のほとんどの VAX MACRO モジュールを自動的に移植できるようにするために提供されており,高速な浮動小数点性能を目的としたものではありません。

エミュレーション・ルーチン呼び出しのオーバヘッドに加えて, OpenVMS Alpha システムでは,すべての浮動小数点オペランドはメモリで渡す必要があります。これは,Alpha アーキテクチャには,整数レジスタから浮動小数点レジスタに直接値を移動する命令がないためです。また,実行される最初の浮動小数点命令で,プロセスの FEN (浮動小数点有効) ビットがオンになり,イメージが実行されているかぎり,浮動小数点レジスタ・セット全体がコンテキスト・スイッチのたびに保存および復元されます。

2.10.1 OpenVMS VAX と OpenVMS Alpha / I64 の実装の違い

OpenVMS VAX システムと OpenVMS Alpha / I64 システムの実装の違いを以下のリストに示します。

  • 浮動小数点命令と不可分性
    浮動小数点命令はすべてサブルーチン呼び出しによってエミュレートされるため,不可分でも再実行可能でもありません。また,.PRESERVE ATOMICITY 指示文や /PRESERVE=ATOMICITY オプションを使用して不可分にすることもできません。さらにレジスタ R16 〜 R28 が命令の前後で保護されるという保証もありません

  • 引数レジスタの使用
    引数は,引数レジスタ ( OpenVMS Alpha システムでは R16 〜 R21) によってエミュレーション・ルーチンに渡されます。浮動小数点命令でこれらのレジスタを引数として使用すると,正常に動作しません。
    OpenVMS I64 システムでは,最初のパラメータはレジスタ R16 〜 R21 ではなく,レジスタ R32 〜 R39 で渡されます。そのため,引数レジスタは 6 個ではなく 8 個あります。また, OpenVMS I64 では, MACRO-32 コンパイラはこれらのレジスタを名前で参照する手段を提供していません。そのため,これらのレジスタの使用が競合するようなコードを記述する可能性はありません。
    OpenVMS Alpha システムでは,浮動小数点命令を使用する場合の AP ベースの参照の問題を防ぐには,これらの参照を含むルーチンのエントリ・ポイントで /HOME_ARGS=TRUE を指定するのが最も簡単です。これにより,すべての AP ベースの参照が,引数レジスタではなくプロシージャ・フレームから読み込まれるため,命令を変更する必要がありません。
    /HOME_ARGS=TRUE を使用しないと, AP レジスタ・ベースのパラメータ参照を浮動小数点命令のオペランドとして含むソース・コードは,変更する必要があります。まず AP ベースのオペランドを一時レジスタにコピーし,浮動小数点命令ではその一時レジスタを使用します。たとえば,次のコードがあるとします。

    MOVF     @8(AP), @4(AP) 
    


    これを次のように変更します。

    MOVL    8(AP), R1 
    MOVL    4(AP), R2 
    MOVF    (R1),(R2) 
    


    OpenVMS I64 システムでは,入力引数レジスタは出力引数レジスタとは分離されていることに注意してください。

  • OpenVMS Alpha システムでの D_floating 形式
    Alpha アーキテクチャでは, D_floating 形式は完全にはサポートされていません。すべての算術演算または変換は, D_floating 形式を G_floating 形式に変換し, G_floating 形式で演算を行った後に,元の D_floating 形式に変換する必要があります。その結果,D_floating 形式の仮数部が 3 ビット失われる上,変換に時間がかかります。そのため,D_floating 形式を使用しても得るものはありません。互換性のためだけに使用可能になっていますが,精度が少し低下するため注意が必要です。

  • OpenVMS I64 システムでの VAX 浮動小数点形式
    Itanium アーキテクチャでは, IEEE の S 形式と T 形式だけがサポートされているため,すべての算術演算または変換は, D_floating 形式と G_floating 形式を T_floating 形式に変換し, T_floating 形式で演算を行ってから,元の D_floating 形式または G_floating 形式に戻すことで行われます。その結果,D_floating 形式の仮数部が 3 ビット失われる上,変換に時間がかかります。そのため,D_floating 形式を使用しても得るものはありません。互換性のためだけに使用可能になっていますが,精度が少し低下するため注意が必要です。同様に,すべての F_floating 演算は,S_floating に変換し,演算を行ってから F_floating に戻すことで実行されます。

  • オーバフロー・トラップ
    整数オーバフローや浮動小数点アンダフローに対してトラップを有効にすることはできません。 Alpha システムは浮動小数点オーバフローに対して常にトラップを生成します。 /ENABLE 修飾子と .ENABLE 指示文を使用しても,オーバフロー・トラップには影響を与えません。 OpenVMS VAX システム上で予測可能な結果になるオーバフロー・トラップは, OpenVMS Alpha システムや OpenVMS I64 システムでも同じ結果になります。

  • ダーティ・ゼロ
    ダーティ・ゼロをなくすようにコードを変更する必要があります。 VAX のすべての浮動小数点形式における真のゼロは,すべてのビットにゼロが設定されています。指数ビットがすべてゼロでも,残りのいずれかのビットが 1 の場合,ダーティ・ゼロと呼ばれ, OpenVMS VAX システムではゼロとして扱われます。 OpenVMS Alpha システムでは,予約オペランド・トラップが発生します。
    OpenVMS I64 は,VAX 形式の浮動小数点をサポートしていません。しかし,VAX 浮動小数点エミュレーション・ルーチンにより VAX と同じ動作が保たれます。

  • 引数の形式に関する制限
    これらの命令はマクロで実現されているため,引数の形式に関する制限が 1 つあります。マクロの呼び出しでは,先頭にサーカンフレックス (^) があると,パラメータが文字列であることを意味するものと解釈され,サーカンフレックスの直後の文字は文字列の区切り文字と解釈されます。そのため, ^x20(SP) のようにオペランド型の指定で始まる引数は使用できません。 #^XFF などのイミディエイト・モード引数は,先頭の文字がサーカンフレックスでないため,オペランド型指定を使用できます。

  • 浮動小数点数の戻り値
    ルーチンを呼び出し,浮動小数点の戻り値が R0 に格納されることを期待している MACRO プログラムでは,呼び出し元のルーチンと呼び出されるルーチンの間に「ジャケット」が必要となります。ジャケットの目的は,浮動小数点レジスタ 0 から R0 に戻り値を移動させることです。



2.10.2 他の言語のルーチンに対する影響

このサポートでは,浮動小数点レジスタ・セットがコンパイラから見えるようになるわけではありません。整数レジスタで浮動小数点演算ができるようになるだけです。つまり,他の言語で記述されたルーチンがVAX MACRO ルーチンを呼び出したり, VAX MACRO ルーチンから呼び出される場合は,浮動小数点数値を入力または出力として使用できません。他の言語のコンパイラは,これらの値を浮動小数点レジスタで渡します。浮動小数点の引数を VAX MACRO ルーチンに渡したり, VAX MACRO ルーチンから受け取るには,必ずポインタを使用します。

他の言語の実行時ライブラリ (RTL) ルーチンを呼び出す場合にもこれが当てはまります。たとえば,MTH$RANDOM を呼び出すと,浮動小数点数値が浮動小数点レジスタ F0 に格納されて返されます。コンパイラは直接 F0 を読み取ることはできません。 MTH$RANDOM を呼び出して結果を R0 に移動するジャケット・ルーチンを別の言語で作成するか,移動だけを行うルーチンを別に記述する必要があります。

2.11 VAX の不可分性と細分性の維持

VAX アーキテクチャには,ユニプロセシング・システムで,読み取り-変更-書き込みメモリ操作を単一の割り込み不可能な操作として実行する命令が含まれています。 不可分性は,メモリを一度の操作で変更できる能力のことを指します。このような命令は複雑で,性能が著しく落ちるため, Alpha システムまたは I64 システムの読み取り-変更-書き込み操作は,不可分でなく,割り込み可能な命令シーケンスとしてのみ実行できます。

さらに,VAX の命令では,周囲のメモリに影響を与えることなく,メモリ中の単独のアラインされた,またはアラインされていないバイト,ワード,ロングワードをアドレス指定できます。 (データ項目は,項目のアドレスがバイト単位のサイズの偶数倍になっている場合に アラインされていると見なされます。) 細分性は,アラインされているロングワードの一部に対して独立に書き込みが行えることを示します。

バイト,ワード,アラインされていないロングワードのアクセスも性能を著しく低下させるため, OpenVMS Alpha システムでは,アラインされているロングワードとクォドワードにしかアクセスできません。そのため,単一のバイト,ワード,アラインされていないロングワードを書き込むための命令シーケンスを実行すると,周囲のバイトが読み込まれて書き戻されます。

Itanium にはバイトとワードにアクセスするための命令がありますが,アラインされていない場合,性能が低下します。

これらのアーキテクチャ上の違いにより,特定の条件ではデータが破壊される可能性があります。

OpenVMS Alpha システムでは,不可分性と細分性の維持は,他のスレッドがメモリを変更できないようにロックすることで実現されるのではなく,読み取り-変更-書き込み操作の間にメモリが変更されたかどうかを判断する手段を提供することで実現されます。変更された場合は,読み取り-変更-書き込み操作が再度実行されます。

OpenVMS I64 システムでは,不可分性は OpenVMS Alpha と同様に操作をリトライすることで実現されます。

データの一貫性を保証するため,コンパイラには,以降の項で説明する条件で使用する修飾子と指示文があります。

2.11.1 不可分性の維持

OpenVMS VAX , OpenVMS Alpha ,および OpenVMS I64 のマルチプロセシング・システムでは,並列に動作する複数のスレッドが書き込み可能なグローバル・セクションにある共用データを変更するアプリケーションは,データに対するアクセスを同期させる何らかの手段を必要とします。 OpenVMS VAX のシングル・プロセッサ・システムでは,メモリの変更命令だけで共用データへのアクセスを同期させるのに十分です。しかし, OpenVMS Alpha システムや OpenVMS I64 システムでは,これだけでは不十分です。

メモリ変更オペランドを使用した VAX 命令に対して,読み取り-変更-書き込み操作の一貫性を保証するために,コンパイラでは /PRESERVE=ATOMICITY オプションが使用できます。また,必要に応じて VAX MACRO ソース・コードのセクションに .PRESERVE ATOMICITY 指示文と .NOPRESERVE ATOMICITY 指示文を挿入し,不可分性の有効と無効を切り替えることもできます。

たとえば,以下の命令があるとします。この命令は,R1 が指すデータに対する読み込み,変更,書き込みシーケンスを要求します。

INCL (R1) 

OpenVMS VAX システムでは,マイクロコードがこれら 3 つの操作を実行します。そのため,シーケンスが完全に完了するまで割り込みは発生しません。

OpenVMS Alpha システムでは,この 1 つの VAX 命令を実行するために,以下の 3 つの命令を実行する必要があります。

LDL     R27, (R1) 
ADDL    R27, 1, R27 
STL     R27, (R1) 

同様に OpenVMS I64 システムでは,以下の 4 つの命令を実行する必要があります。

ld4     r22 = [r9] 
sxt4    r22 = r22 
adds    r22 = 1, r22 
st4     [r9] = r22 

この Alpha/ Itanium コード・シーケンスの問題は,それぞれの命令の間で割り込みが発生する可能性があるという点です。割り込みにより AST ルーチンが実行されるか, LDL と STL の間に別のプロセスがスケジュールされ, AST または他のプロセスが R1 が指すデータを更新すると, STL は古いデータに基づく結果 (R1) を格納します。

不可分な操作が必要な場合で, /PRESERVE=ATOMICITY (または .PRESERVE ATOMICITY) を指定した場合は,コンパイラは INCL (R1) に対して次の Alpha 命令シーケンスを生成します。

Retry:  LDL_L   R28,(R1) 
        ADDL    R28,#1,R28 
        STL_C   R28,(R1) 
 
        BEQ     R28, fail 
         . 
         . 
         . 
fail:   BR      Retry 

Itanium での命令シーケンスは次のとおりです。

$L3:    ld4            r23 = [r9] 
        mov.m          apccv = r23 
        mov            r22 = r23 
        sxt4           r23 = r23 
        adds           r23 = 1, r23 
        cmpxchg4.acq   r23, [r9] = r23 
        cmp.eq         pr0, pr6 = r22, r23 
  (pr6) br.cond.dpnt.few $L3   

OpenVMS Alpha システムでは,このシーケンス中に現在のプロセッサまたは他のプロセッサ上の他のコード・スレッドによって (R1) が変更されると, STL_C (Store Longword Conditional) 命令が (R1) を更新せず, R28 に 0 を書き込むことでエラーになったことを通知します。この場合,コードは元に分岐し,干渉なく操作が完了するまで操作がリトライされます。

Alpha アーキテクチャの分岐予測ロジックでは,後方条件分岐が成立すると想定されるため, BEQ Retry の代わりに,BEQ Fail と BR Retry が実行されます。この操作はめったにリトライする必要がないため,分岐成立が想定されない前方条件分岐を行う方が効率が良くなります。

OpenVMS Alpha システムでは,不可分性を保持するための仕組みにより,ユニプロセッサシステムとマルチプロセッサ・システムの両方にこの不可分性の保証が適用されます。この保証は実際の変更命令だけに適用され,以降のメモリ・アクセスや以前のメモリ・アクセスにはインターロックが拡張されません ( 第 2.11.6 項 を参照)。

OpenVMS I64 版のコードでは, compare-exchange 命令 (cmpxchg) を使用してロックされたアクセスが実現されますが,効果は同じです。変更しようとしているメモリが他のコードによって変更された場合,コードがループ・バックし,操作をリトライします。


目次 索引

© 2012 Hewlett-Packard Development Company, L.P.