日本-日本語
日本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 コンパイラ
ポーティングおよびユーザーズ・ガイド


目次 索引

第 3 章
ソースに対する推奨される変更と必要な変更

この章では,VAX MACRO コードを OpenVMS Alpha または OpenVMS I64 に移植する際に調べる必要があるコーディング構造について説明します。ここで説明するコーディング構造がモジュール中にあると,移植に時間がかかります。

コンパイラはすべての VAX MACRO コードを透過的に変換できるわけではありません。 OpenVMS Alpha または OpenVMS I64 のコードに直接コンパイルできないコードも多数あります。コンパイラはこのようなコードの多くを検出し,診断メッセージを出力します。正常にコンパイルするためには,これらのコードを削除するか変更する必要があります。

ほとんどの場合,ソース・コードの変更が必要です。例外がある場合はその旨明記してあります。

この章のトピックは以下のとおりです。



3.1 スタックの使用

OpenVMS の呼び出し規則では, OpenVMS Alpha システムおよび OpenVMS I64 システムのスタック・フレームの形式が定義されています。これは, OpenVMS VAX システムで定義されている形式とは大きく異なります。コードが OpenVMS VAX のスタック・フレームの形式に依存している場合は, OpenVMS Alpha システムまたは OpenVMS I64 システムに移植する際に変更する必要があります。

3.1.1 プロシージャ・スタック・フレームの参照

FP からの正のスタック・オフセットに対する参照はできず,参照するとコンパイラでエラーとなります。 この規則に対する 1 つの例外は,VAX MACRO コードでルーチン・アドレスを FP が指すスタック位置に移動することにより動的な条件ハンドラを設定する場合です。コンパイラはこれを検出し,このようなハンドラを設定するための適切な Alpha または Itanium のコードを生成します。しかし,0(FP) への書き込みが JSB ルーチンの内部にある場合は,コンパイラはエラーとして出力します。 コンパイラは負の FP オフセットを許し,これは,プロシージャの先頭で割り当てたスタック・ストレージを参照するために使用されます。

推奨される変更

スタック・フレームの参照は, OpenVMS Alpha または OpenVMS I64 の形式に変換するのではなく,可能であればすべて削除してください。たとえば,問題のコードが,保存されたレジスタの値を変更しようとしていた場合は,新しい値を一時的にスタックに格納し,ルーチンの出口でレジスタ値を設定します (エントリ・レジスタ・マスクからそのレジスタを削除します)。

3.1.2 現在のスタック・フレームの外側の参照

コンパイラは, VAX MACRO モジュール全体でスタックの深さを監視することで,呼び出し元がプッシュしたデータをルーチン内で参照している箇所を検出し,エラーを出力します。

推奨される変更

呼び出し元がスタックにプッシュしたデータをルーチン内で参照している部分を削除する必要があります。代わりに,必要なデータをパラメータとして渡すか,データの読み込み先となるスタック・ベースへのポインタを渡します。

3.1.3 アラインされていないスタックの参照

ルーチンの呼び出し時に,スタックがオクタワード境界にアラインされていない場合は,コンパイラはスタックをオクタワード境界にアラインします。一部のコードでは,スタック上に構造を構築する際に,アラインされていないスタック参照を行ったり,スタック・ポインタがアラインされていない状態になります。コンパイラは,これに対して情報レベルのメッセージを出力します。

推奨される変更

スタックにプッシュするデータ要素や構造体に十分なパディングを追加するか,データ構造のサイズを変更します。アラインされていないスタック参照は,VAX の性能にも影響を与えるため,これらの修正を,VAX,Alpha, Itanium アーキテクチャ向けに設計されたコードに適用することをお勧めします。

3.1.4 スタック上のデータ構造の構築

一般的なコーディング・スタイルとしては,要素をプッシュすることでスタック上に構造を作成し,自動デクリメントによってスタック・ポインタを移動させ領域を割り当てます。この方法の問題を以下に挙げます。

  • 構造体にパディングを追加してフィールドをアラインするために,構築しようとしている構造体の SDL ソースを変更すると,コードが破壊されます。コードに assume 文が含まれていない場合は,この問題はコンパイル時に検出されません。

  • フィールドのサイズを拡張すると,現在の命令はすべてのデータにアクセスしなくなりますが,これも検出されません。

推奨される変更

最初の問題を修正し,2 番目の問題を検出するには,この例に示すコーディング・テクニックを使用してください。次のコード例を考えます。

; Build a descriptor on the stack. 
; 
MOVW    length, -(SP) 
MOVB    type,   -(SP) 
MOVB    class,  -(SP) 
MOVAL   buffer, -(SP) 

このコードは,次のコードで置き換えます。

SUBL2   DSC$S_DSCDEF, SP  ; pre-allocate space on stack 
MOVW    length, DSC$W_LENGTH(SP) 
MOVB    type,   DSC$B_DTYPE(SP) 
MOVB    size,   DSC$B_CLASS(SP) 
MOVAL   buffer, DSC$A_POINTER(SP) 



3.1.5 VAX の SP および PC へのクォドワードの移動

VAX と Alpha/ Itanium コンピュータのアーキテクチャ上の違いにより,プログラマの介入なしでは, VAX のスタック・ポインタ (SP) およびプログラム・カウンタ (PC) へのクォドワードの移動を完全にエミュレートすることはできません。 VAX アーキテクチャでは,R14 が SP として定義され, R15 が PC として定義されています。 SP をターゲットとした MOVQ 命令では,次の例に示すように VAX の SP と PC へのロードが同時に実行されます。

MOVQ    R0,SP   ; Contents of R0 to SP, R1 to PC 
 
MOVQ    REGDATA, SP   ; REGDATA to SP 
                      ; REGDATA+4 to PC 

SP を移動先とした MOVQ 命令をコンパイラが見つけると,コンパイラは指定された読み込み元からスタック・ポインタへの符号拡張されたロングワードのロードを生成し,次の情報メッセージを出力します。

%AMAC-I-CODGENINF, (1) Longword update of Alpha SP, PC untouched 

推奨される変更

MOVQ 命令を使用している目的が, VAX の動作を実現することである場合は,次に示すように, MOVL 命令を使用し,その後で目的のアドレスへの分岐を使用することをお勧めします。

MOVL    REGDATA, SP     ; Load the SP 
MOVL    REGDATA+4, R0   ; Get the new PC 
JMP     (R0)            ; And Branch 

MOVQ 命令を使用している目的が,スタック・ポインタに8 バイトの値をロードすることである場合は,次に示すように,代わりに EVAX_LDQ ビルトインを使用してください。

EVAX_LDQ        SP, REGDATA 



3.2 命令ストリーム

この項で説明する VAX MACRO のコーディング・スタイルと VAX 命令は, OpenVMS Alpha や OpenVMS I64 では動作しないか,予期しない結果になります。

3.2.1 命令ストリームに埋め込まれたデータ

コンパイラは,命令ストリームに埋め込まれたデータを検出し,エラーとして報告します。

命令ストリーム中のデータは,多くの場合 JSB 命令の後に .LONG が続いた形になります。この構造により,VAX MACRO コードは,スタック上の戻りアドレスを使用してデータを見つける JSB ルーチンに暗黙的にパラメータを渡すことができます。コード・ストリーム中でデータを使用する方法としてもう 1 つ頻繁に使用されるのは,コードとともにメモリ中にデータを連続させ, 1 つの単位として再配置できるようにすることです。

推奨される変更

暗黙的な JSB パラメータに対しては,パラメータ値をレジスタで渡します。ロングワードよりも大きな値の場合は,データを別のプログラム・セクション (psect) に格納し,そのアドレスを明示的に渡します。

静的なデータは独立したデータ psect にある必要があるため,コードとデータを一緒に再配置するようなコードは,書き直す必要があります。

3.2.2 実行時のコード生成

コンパイラはスタック領域や静的なデータ領域への分岐を検出し,エラーとして出力します。

推奨される変更

命令を構築して後で実行するコード,スタック領域に分岐するコード,静的なデータ領域に分岐するコードは削除するか変更する必要があります。このようなコードがどうしても必要な場合は,条件付けしてそのコードを OpenVMS VAX 用とし,それに相当する適切な OpenVMS Alpha または OpenVMS I64 用のコードを作成してください。

3.2.3 命令サイズへの依存

たとえば,命令の長さに基づいて分岐オフセットを計算するコードは,変更する必要があります。

推奨される変更

ラベルと標準的な分岐を使用するか,計算型 GOTO に対しては CASE 命令を使用してください。

3.2.4 不完全な命令

OpenVMS VAX コードの一部の CASE 命令は,その後にオフセット・テーブルがなく,代わりにリンカによる psect の配置に依存して命令を完成させています。コンパイラは不完全な命令をエラーとして出力します。

推奨される変更

モジュール内の命令を完成させるか,データ psect 内にアドレスのテーブルを作成し,CASE 命令を,テーブルから分岐先アドレスを選択して分岐するようなコードで置き換えます。

3.2.5 トランスレートされない VAX 命令

コンパイラは以下の VAX 命令をトランスレートできないため,エラーとして出力します。

  • LDPCTX および SVPCTX

  • XFC

  • ESCD,ESCE,および ESCF

  • BUGx

推奨される変更

通常これらの命令は, VAX アーキテクチャに大きく依存するコードに現れます。このようなコードを OpenVMS Alpha システムまたは OpenVMS I64 システムに移植するには,書き直す必要があります。

3.2.6 内部プロセッサ・レジスタの参照

以下の命令には特に注意してください。

  • MFPR

  • MTPR

推奨される変更

OpenVMS Alpha システムでは,これらの命令が正しい Alpha 内部プロセッサ・レジスタ (IPR) を参照していることを確認してください。正しい内部プロセッサ・レジスタを参照していないと,エラーになります。 Alpha の内部プロセッサ・レジスタについての詳細は, Alpha Architecture Reference Manual を参照してください。

OpenVMS I64 システムでは,コンパイラは VAX 命令 MFPR と MTPR を直接サポートしていません。ただし,OpenVMS で提供されている一連のマクロがあり,このマクロが同じ機能を実行するシステム・サービスを呼び出します。

3.2.7 BICPSW 命令での条件コード Z および N の使用

BICPSW 命令はサポートされていますが,条件コード Z とN は同時には設定できません。条件コード Z を設定すると条件コード N がクリアされ,逆に条件コード N を設定すると条件コード Z がクリアされます。

推奨される変更

コードで両方の条件コードを同時に設定している場合は,コードを変更してください。

3.2.8 インターロックされるメモリ命令

Alpha Architecture Reference Manual では,インターロックされるメモリ命令の使用に対する厳密な規則が記述されています。特に,LDxL/STxC シーケンスの内部での分岐またはこのシーケンス内への分岐は禁止されています。インターロックされるシーケンスから外に向かう分岐は正しいため,変更する必要はありません。 Alpha 21264 (EV6) プロセッサとそれ以降のすべての Alpha プロセッサでは,それ以前のプロセッサと比較して,より厳密にこの規則に従うことを義務付けています。 Alpha 21264 プロセッサは, OpenVMS Alpha Version 7.1-2 で初めてサポートされました。

MACRO コンパイラが Macro-32 ソース・コードから生成したコードは,これらの規則に従っています。ただし,これらの命令をソース・コード中に直接記述できるように, EVAX_LQxL ビルトインと EVAX_STxC ビルトインが用意されています。

これらの命令が,インターロックされるメモリ命令を使用するための規則に従って使用されていることが保証できるように, MACRO コンパイラにチェックが追加されています。この機能は, OpenVMS Alpha Version 7.1-2 ではバージョン 3.1 のコンパイラから, OpenVMS Alpha Version 7.2 ではバージョン 4.1 のコンパイラから追加されています。

OpenVMS I64 システムでは,コンパイラは,EVAX_LDxL ビルトインを,ロードした値をハードウェアの AR.CCV レジスタに保存すると同時に,後で使用するためにローカルなコピーを保持する命令に置き換えます。 EVAX_STxC ビルトインは, EVAX_LDxL ビルトインによって以前保存された値と比較する compare-exchange (cmpxchg) 命令に置き換えられます。コンパイラは,インターロックされる命令シーケンスへの分岐に関する Alpha のすべての規則を適用します。

ここで述べた状況下では,コンパイラによって以下の警告メッセージが出力されます。

BRNDIRLOC, branch directive ignored in locked memory sequence

説明: LDx_L/STx_C シーケンス中に .BRANCH_LIKELY 指示文が見つかりました。
対処: ありません。 .BRANCH_LIKELY 指示文は無視され,他のコーディング・ガイドラインの違反がなければ,コードは書かれているとおりに動作します。
BRNTRGLOC, branch target within locked memory sequence in routine 'routine_name'

説明: 分岐命令の分岐先が LDx_L/STx_C シーケンスの内部になっています。
対処: この警告が出ないようにするには,ソース・コードを書き直して, LDx_L/STx_C シーケンスの内部での分岐やこのシーケンス内への分岐をなくします。インターロックされるシーケンスから外部への分岐は有効であり,エラーになりません。
MEMACCLOC, memory access within locked memory sequence in routine 'routine_name'

説明: LDx_L/STx_C シーケンス内にメモリの読み書きがあります。ソース・コード中の "MOVL data, R0" などの明示的な参照の場合と,メモリへの暗黙的な参照の場合があります。たとえば,データ・ラベルのアドレスのフェッチ ("MOVAB label, R0" など) は,リンケージ・セクションからの読み込みによって実現されます。リンケージ・セクションは,外部参照を解決するために使用されるデータ領域です。
対処: この警告が出ないようにするには,すべてのメモリ・アクセスを LDx_L/STx_C シーケンスの外に移動します。
RETFOLLOC, RET/RSB follows LDx_L instruction

説明: LDx_L 命令の後, STx_C 命令が出現する前に RET 命令または RSB 命令が見つかりました。これは,不適切なロック・シーケンスです。
対処: RET 命令や RSB 命令が LDx_L 命令と STx_C 命令の間に来ないようにコードを変更します。
RTNCALLOC, routine call within locked memory sequence in routine 'routine_name'

説明: LDx_L/STx_C シーケンス内でルーチンを呼び出しています。 "JSB subroutine" のようにソース・コード中に明示的な CALL/JSB がある場合と,別の命令の結果として呼び出す場合があります。たとえば,MOVC や EDIV などのいくつかの命令では,実行時ライブラリの呼び出しが生成されます。
対処: この警告が出ないようにするには,ルーチン呼び出しや,ルーチン呼び出しを生成する命令を,コンパイラの指示どおりに LDx_L/STx_C シーケンスの外へ移動します。
STCMUSFOL, STx_C instruction must follow LDx_L instruction

説明: LDx_L 命令が見つかる前に STx_C 命令が見つかりました。これは,不適切なロック・シーケンスです。
対処: LDx_L 命令の後に STx_C 命令が来るようにコードを変更します。

推奨される変更

インターロックされるメモリ命令の不適切な使用が検出された場合は,警告メッセージで説明されている推奨される対処に従ってください。


目次 索引

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