日本-日本語 |
|
|
|
OpenVMS マニュアル |
|
HP OpenVMS MACRO コンパイラ
|
目次 | 索引 |
この付録では,MACRO Compiler for OpenVMS systems 専用の指示文について説明します。
MACRO Compiler for OpenVMS systems は, VAX MACRO and Instruction Set Reference Manual で説明している,標準的な VAX MACRO アセンブラの指示文のほとんどをサポートしています。ただし,VAX MACRO アセンブラでサポートされているいくつかの指示文は,コードがコンパイルされる場合には意味を持ちません。そのため,そのような指示文があると,コンパイラはメッセージを出力して実行を継続します。 /NOFLAG=DIRECTIVES を指定することで,これらの指示文に対するメッセージ出力を無効にできます。
MACRO Compiler for OpenVMS systems には,以下に示す専用の指示文があります。
これらの指示文に対して特定の引数を使用し,レジスタ・セットを指示することができます。レジスタ・セットを指定するには,次の例のように,複数のレジスタをコンマで区切り,山括弧で囲みます。
B.1 VAX MACRO アセンブラの指示文
注意
MACRO Compiler for OpenVMS systems を使用するときには, .ASCID 指示文に対する引数の長さは,996 文字に制限されています。 VAX MACRO アセンブラにはこのような制限はありません。
B.2 MACRO コンパイラ専用の指示文
<R1,R2,R3> |
レジスタ・セット中に 1 つしかレジスタがない場合は,次の例のように,山括弧は必要ありません。
R1 |
.BRANCH_LIKELY |
次の分岐が成立する可能性が高いことをコンパイラに指示します。
.BRANCH_LIKELY
この指示文にはパラメータはありません。
Alpha ハードウェアでは,前方条件分岐は成立せず,後方条件分岐は成立すると予測されます。 Alpha アーキテクチャに基づき,これらの想定がコンパイラに組み込まれており,条件分岐のコード生成に影響を与えます。.BRANCH_LIKELY が前方条件分岐の前にあると,コンパイラは条件分岐を変更して,可能性が低いパスが,可能性が高い分岐の代わりに前方分岐となるようにコードの順序を入れ替えます。
Itanium アーキテクチャには,各分岐命令に対して明示的な分岐予測機能があります。しかし,ここでもコンパイラは,前方分岐は成立せず,後方分岐は成立するという仮定に従ってコードの順序を変更します。コンパイラは,分岐予測フラグを適切に設定します。
#1 |
---|
MOVL (R0),R1 .BRANCH_LIKELY BNEQ 10$ . . . 10$ |
コンパイラは,BNEQ 命令とラベル 10$ の間にあるコードを,モジュールの最後に移動し, BNEQ 10$ を,移動したコードへの BEQL に変更します。次に,BEQL 命令のすぐ後から,ラベル 10$ から始まるコードを生成します。
.BRANCH_UNLIKELY |
コンパイラに対して,その下にある分岐は成立する可能性が低いことを指示します。その結果,コンパイラはこの想定を取り入れたコードを生成します。
.BRANCH_UNLIKELY
この指示文にはパラメータはありません。
分岐予測を行う際にコンパイラが使用する想定については, .BRANCH_LIKELY 指示文の説明を参照してください。OpenVMS Alpha システムでは, .BRANCH_UNLIKELY が後方条件分岐の前にあると,コンパイラは条件分岐とコードを変更して,無条件後方分岐命令への前方分岐になるようにします。 .BRANCH_UNLIKELY は,単にそのまま次に進むよりも可能性が低いというだけでなく,分岐の可能性が非常に低い場合にだけ使用します。
OpenVMS I64 システムでは, .BRANCH_UNLIKELY が後方条件分岐の前にあると,コンパイラは,生成された Itanium 命令に対して,適切な分岐予測フラグを使用します。
.BRANCH_UNLIKELY は,前方条件分岐の前に指定しても効果がありません。
#1 |
---|
MOVL #QUEUE,R0 ;Get queue header 10$: MOVL (R0),R0 ;Get entry from queue BEQL 20$ ;Forward branch assumed unlikely . . ;Process queue entry . TSTL (R0) ;More than one entry (known to be unlikely) .BRANCH_UNLIKELY BNEQ 10$ ;This branch made into forward 20$: ;conditional branch |
.BRANCH_UNLIKELY 指示文をここで使用している理由は, Alpha ハードウェアによって, 10$ への後方分岐が成立する可能性が高いと予測されるためです。プログラマは,それがまれなケースであることを知っているため,この指示文を使用してその分岐を,成立しないと予測される前方分岐に変更しています。
.CALL_ENTRY |
呼び出されるルーチンのエントリ・ポイントをコンパイラに対して宣言します。このエントリ・ポイント宣言によって,ルーチンで変更され, scratch または output として宣言されていないすべてのレジスタ (R0 と R1 を除く) に対して, 64 ビット全体の保存と復元が行われます。
.CALL_ENTRY [max_args=number] [,home_args=TRUE|FALSE] [,quad_args=TRUE|FALSE] [,input] [,output] [,scratch] [,preserve] [,label]
max_args=number
呼び出されるプロシージャが期待する引数の最大数です。コンパイラは,引数リストをホーミングする必要がある場合に,スタック・フレームの固定の一時領域に割り当てるロングワードの数としてこの引数を使用します。ホーミングが必要でない場合は, max_args の個数は必要ありません。引数リストのホーミングが必要なプロシージャのエントリ・ポイントで max_args が指定されていないと,コンパイラはメッセージを出力します。引数リストをホーミングする際に, max_args が 14 を超える .CALL_ENTRY ルーチンに対しては,受け取った引数カウントと max_args のうち,小さい方が使用されます。
home_args=TRUE|FALSE
呼び出されるプロシージャの引数リストをホーミングする必要があるかどうかをコンパイラに指示します。 home_args 引数は,引数リストをホーミングしなくてはならない状況にあるかどうかを判断する,コンパイラのデフォルトのロジック ( 第 2.4.1 項 を参照) を変更します。quad_args=TRUE|FALSE
呼び出されるプロシージャの引数リストにクォドワード参照があるかどうかをコンパイラに指示します。input=<>
ルーチンが入力値を受け取るレジスタを示すレジスタ・セットです。このレジスタ・セットは,指定したレジスタに,ルーチンの入口で意味のある値が格納されており,コンパイラが最初のレジスタの使用を検出する前であっても,一時レジスタとして使用できないことをコンパイラに指示します。このレジスタ・セットにレジスタを指定すると,次の 2 つの場合にコンパイラの一時レジスタの使用に影響を与えます。
- 最適化オプション VAXREGS ( OpenVMS Alpha のみ) を使用している場合。この最適化を有効にすると, VAX MACRO コードで明示的に使用されていないすべての VAX レジスタを,コンパイラが一時レジスタとして使用できるようになります。
- Alpha または Itanium のいずれかのレジスタ (R13 以降) を,明示的に使用している場合。
上記いずれかに該当する場合は,入力として使用するレジスタを input 引数に指定しないと,コンパイラがそのレジスタを一時レジスタとして使用し,入力値が壊れるおそれがあります。
このレジスタ・セットは,コンパイラのデフォルトのレジスタ保護動作には影響を与えません。 VAXREGS 最適化スイッチを使用しない場合や, Alpha レジスタを使用しない場合は,入力マスクはルーチンの文書化のためにのみ使用されます。
output=<>
ルーチンがその呼び出し元に返す値を代入するレジスタを示すレジスタ・セットです。このレジスタ・セットに含まれるレジスタに対しては,ルーチンによって変更される場合でも,コンパイラによる保存と復元が行われません。このレジスタ・セットは,指定されたレジスタにはルーチンの出口で意味のある値が格納されており,コンパイラが最後のレジスタの使用を検出した後でも,一時レジスタとして使用できないことをコンパイラに対して通知します。このレジスタ・セットにレジスタを指定すると,以下の 2 つの場合にコンパイラの一時レジスタの使用に影響を与えます。
- 最適化スイッチ VAXREGS ( OpenVMS Alpha のみ) を使用している場合。この最適化を有効にすると, VAX MACRO コードで明示的に使用されていないすべての VAX レジスタを,コンパイラが一時レジスタとして使用できるようになります。
- Alpha または Itanium のいずれかのレジスタ (R13 以降) を,明示的に使用している場合。
上記いずれかに該当する場合は,出力として使用するレジスタを output 引数で指定しないと,コンパイラがそのレジスタを一時レジスタとして使用し,出力値が壊れるおそれがあります。
scratch=<>
ルーチン内で使用されているものの,ルーチンの入口と出口で保存と復元を行うべきでないレジスタを示すレジスタ・セットです。ルーチンの呼び出し元は,出力値を受け取ることを期待しておらず,レジスタが保護されることも期待していません。このレジスタ・セットに含まれるレジスタに対しては,ルーチンによって変更される場合でも,コンパイラによる保存と復元が行われません。これは,コンパイラの一時レジスタの使用にも関係します。 OpenVMS Alpha システムでは,レジスタ R13 以降がルーチンのソース・コードで使用されていなければ,コンパイラはこれらのレジスタを一時レジスタとして使用します。 OpenVMS Alpha システムでは, R13 〜 R15 が変更される場合は保護する必要があるため,コンパイラはこれらのレジスタを使用する場合には保護します。
しかし,これらのレジスタが scratch レジスタ・セット宣言に指定されている場合は,コンパイラは,一時レジスタとしてそれを使用する場合に保護しません。その結果,これらのレジスタは,ルーチンのソースで使用されていなくても, scratch セットに指定されていれば,ルーチンの出口では壊れている可能性があります。 VAXREGS ( OpenVMS Alpha のみ) による最適化を使用した場合は,これはレジスタ R2 〜 R12 にも適用されます。
OpenVMS I64 システムでは,コンパイラはこれらのレジスタを一時レジスタとして使用しません。
preserve=<>
ルーチン呼び出しの前後で保護する必要があるレジスタを指示するレジスタ・セットです。これには,変更され, 64 ビットの内容全体を保存および復元する必要があるレジスタだけを含める必要があります。このレジスタ・セットを指定すると,コンパイラによってレジスタが自動的に保護されているかどうかにかかわらずレジスタは保護されます。 R0 と R1 はスクラッチ・レジスタであるため,このレジスタ・セットで指定しないかぎり,標準の定義を呼び出しただけでは,コンパイラはこれらのレジスタの保存と復元を実行しません。レジスタ R16 以降は指定できません。
このレジスタ・セットは, output レジスタ・セットと scratch レジスタ・セットより優先されます。 preserve レジスタ・セットと, output レジスタ・セットまたは scratch レジスタ・セットの両方でレジスタを指定すると,コンパイラは次の警告を報告します。
%AMAC-W-REGDECCON, register declaration conflict in routine A
label=name
VAX MACRO の .ENTRY 指示文と同じように,オプションでラベルを指定することができます。これは,モジュールを OpenVMS VAX と OpenVMS Alpha や OpenVMS I64 で共通にする場合や, OpenVMS VAX バージョンで .MASK 指示文のあるエントリを参照する必要がある場合, OpenVMS Alpha または OpenVMS I64 のバージョンで特別な .CALL_ENTRY パラメータを使用する必要がある場合に使用できます。 label パラメータが指定され,シンボル VAX が定義されていると, .ENTRY 指示文が使用されます ( 第 1.7.3 項 を参照) 。シンボル VAX が定義されていない場合は,ラベルを作成して通常の .CALL_ENTRY の動作をします。 label は最初のパラメータではありません。そのため,単純に .ENTRY を .CALL_ENTRY に置き換えることはできません。 label パラメータ宣言を使用する必要があります。
.CALL_LINKAGE ( OpenVMS I64 のみ) |
名前付きリンケージまたは匿名リンケージをルーチン名に関連付けます。コンパイラが,ルーチン名をターゲットとする CALLS,CALLG,JSB,BSBB, BSBW のいずれかの命令を見つけると,関連付けられているリンケージを使用して,呼び出しの前後で保存と復元が必要なレジスタを決定します。
.CALL_LINKAGE routine_name [,linkage_name] [,input] [,output] [,scratch] [,preserve]
routine_name
リンケージに関連付けるルーチンの名前です。linkage_name =
.DEFINE_LINKAGE 指示文で定義したリンケージの名前です。 linkage_name を指定する場合,パラメータ input,output, scratch,preserve は指定できません。input=<>
routine_name が入力値を受け取るレジスタを示すレジスタ・セットです。このパラメータは文書化のためにのみあります。input レジスタ・セットを指定する場合, linkage_name は指定できません。
output=<>
routine_name がルーチンの呼び出し元に返す値を代入するレジスタを示すレジスタ・セットです。このレジスタ・セットに含まれているレジスタは,呼び出しの前後で保存と復元が行われません。output レジスタ・セットを指定する場合は, linkage_name は指定できません。
scratch=<>
ルーチン内で使用するレジスタを示すレジスタ・セットです。scratch レジスタ・セットを指定する場合は, linkage_name は指定できません。
preserve=<>
routine_name が保護するレジスタを示すレジスタ・セットです。このレジスタ・セットに含まれているレジスタは,ルーチンの呼び出しの前後で保存と復元が行われません。保存と復元は,呼び出されるルーチンが行うためです。preserve レジスタ・セットを指定する場合は, linkage_name は指定できません。
.DEFINE_LINKAGE ( OpenVMS I64 のみ) |
以降の .CALL_LINKAGE 指示文または .USE_LINKAGE 指示文で使用可能な名前付きリンケージを定義します。
.DEFINE_LINKAGE linkage_name [,input] [,output] [,scratch] [,preserve]
linkage_name
定義するリンケージの名前です。input=<>
このリンケージを持つルーチンが入力値を受け取るレジスタを示すレジスタ・セットです。このパラメータは文書化のためにのみあります。output=<>
このリンケージを持つルーチンが,その呼び出し元に返す値を代入するレジスタを示すレジスタ・セットです。このレジスタ・セットに含まれているレジスタは,呼び出しの前後で保存と復元が行われません。scratch=<>
このリンケージを持つルーチンで使用されるレジスタを示すレジスタ・セットです。このパラメータは文書化のためにのみあります。preserve=<>
このリンケージを持つルーチンが内容を保護するレジスタを示すレジスタ・セットです。このレジスタ・セットに含まれているレジスタは,ルーチンの呼び出しの前後で保存と復元が行われません。この作業は,呼び出されるルーチンで行うためです。
目次 | 索引 |
|