[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]

8 アプリケーション内の条件処理コードの確認

この章では,アプリケーション内の条件処理コードに対して,VAXアーキテクチャと Alphaアーキテクチャの違いがどのような影響を与えるかについて説明します。


8.1 概要

ほとんどの場合,アプリケーションの条件処理コードは Alphaシステムでも正しく機能します。特に,FORTRANのENDやERR,IOSTAT指定子など, アプリケーション開発において, 高級言語で提供される条件処理機能を使用している場合には,問題はありません。 これらの言語機能はアーキテクチャ固有の条件処理機能からアプリケーションを分離します。

しかし,Alpha条件処理機能とそれに対応する VAX条件処理機能の間にはいくつかの違いがあり, 場合によってはソース・コードを変更しなければなりません。次の場合には, ソース・コードの変更が必要です。

この後の節では,これらの変更について詳しく説明し, ソース・コードの変更が必要かどうかを判断するのに役立つガイドラインも示します。


8.2 動的条件ハンドラの設定

OpenVMS Alphaの実行時ライブラリ(RTL)にはLIB$ESTABLISHルーチンがありませんが, OpenVMS VAXのRTLにはこのルーチンがあります。OpenVMS Alphaの呼び出し規則により, 条件ハンドラの設定はコンパイラによって行われます。

条件ハンドラを動的に設定しなければならないプログラムのために,一部の Alpha言語では,LIB$ESTABLISHの呼び出しが特別な方法で取り扱われ,実際に RTLルーチンを呼び出さずに適切なコードを生成します。次の言語は,対応する VAX言語と互換性のある方法でLIB$ESTABLISHをサポートします。


8.3 依存している条件処理ルーチンの確認

ユーザ作成条件処理ルーチンの呼び出しシーケンスは,Alphaシステムでも VAXシステムのときと同じです。条件処理ルーチンは, 例外条件を通知するときにシステムが戻すデータをアクセスするために 2つの引数を宣言します。システムはシグナル・アレイとメカニズム・アレイという 2つの配列を使用して,どの例外条件がシグナルを起動したかを識別する情報を伝達し, 例外が発生したときのプロセッサの状態を報告します。

シグナル・アレイとメカニズム・アレイの形式はシステムで定義され, 『OpenVMS Programming Concepts Manual』に説明されています。Alphaシステムでは, シグナル・アレイに戻されるデータとその形式はVAXシステムの場合と同じです。 図 8-1を参照してください。

図 8-1 VAXシステムとAlphaシステム上の32ビット・シグナル・アレイ


次の表はシグナル・アレイ内の各引数を示しています。

引数 説明
引数の数 AlphaシステムでもVAXシステムでも, この引数には正の整数が格納され,配列内でこの後に続くロングワードの数を示す。
状態コード AlphaシステムでもVAXシステムでも, この引数は32ビットのコードであり, ハードウェアまたはソフトウェア例外条件を一意に識別する。条件コードの形式は Alphaシステムでも変更されておらず, 『OpenVMS Programming Interfaces: Calling a System Routine』 に説明されているとおりである。しかし,Alphaシステムは VAXシステムで戻されるすべての条件コードをサポートするわけではなく, さらにVAXシステムでは戻されない条件コードを定義している。 Alphaシステムで戻すことができないVAX条件コードについては 第8.4節を参照。
オプション・メッセージ・
シーケンス
これらの引数は戻される例外に関する追加情報を提供し, これは各例外に応じて異なる。VAX例外に対するこれらの引数については, 『OpenVMS Programming Concepts Manual』を参照。
プログラム・カウンタ
(PC)
例外がトラップである場合には, 例外が発生したときに次に実行される命令のアドレス。例外がフォルトの場合には, 例外の原因となった命令のアドレス。Alphaシステムでは,この引数にはPCの下位 32ビットが格納される(Alphaシステムでは,PCは64ビットの長さである)。
プロセッサ・ステータス・
ロングワード(PSL)
フォーマッティングした32ビットの引数であり, 例外が発生したときのプロセッサの状態を記述する。Alphaシステムでは, この引数にはAlphaの64ビットのプロセッサ・ステータス(PS)・クォドワードの下位 32ビットが格納される。

Alphaシステムでは,メカニズム・アレイにはVAXの場合と同様のデータが戻されます。 しかし,その形式は異なります。Alphaシステムで戻されるメカニズム・アレイには, 浮動小数点スクラッチ・レジスタだけでなく, 整数スクラッチ・レジスタの内容も保存されます。さらに,Alphaのレジスタは 64ビットの長さであるため,メカニズム・アレイは,VAXシステムのようにロングワード (32ビット)ではなく,クォドワード(64ビット)で構成されます。 図 8-2はVAXシステムと Alphaシステムでのメカニズム・アレイの形式を比較しています。

図 8-2 VAXシステムと Alphaシステムでのメカニズム・アレイ :(クリックで表示)


次の表はメカニズム・アレイ内の各引数を示しています。

引数 説明
引数の数 VAXシステムでは, この引数には正の整数が格納され,配列内でその後に続くロングワードの数を示す。 Alphaシステムでは,この引数はメカニズム・アレイ内のクォドワードの数を示し, 引数カウント・クォドワードの数(Alphaシステムでは常に43)を示すわけではない。
フラグ Alphaシステムでは, この引数には追加情報を伝達するためのさまざまなフラグが格納される。たとえば, ビット0がセットされている場合には,プロセスがすでに浮動小数点演算を実行し, 配列内の浮動小数点レジスタが正しいことを示す( VAXシステムのメカニズム・アレイにはこれに対応する引数はない)。
フレーム・ポインタ(FP) VAXシステムでもAlphaシステムでも, この引数には条件ハンドラを設定したスタックの呼び出しフレームのアドレスが格納される。
深さ VAXシステムでもAlphaシステムでも,この引数には, 例外を発生させたフレームを基準にして, 条件処理ルーチンを設定したプロシージャのフレーム番号を表現する整数が格納される。
リザーブ 予約されている。
ハンドラ・データ・アドレス Alphaシステムでは,この引数には, ハンドラが存在する場合はハンドラ・データ・クォドワードのアドレスが格納される (VAXシステムのメカニズム・アレイにはこれに対応する引数はない)。
例外スタック・フレーム・アドレス Alphaシステムでは, この引数には例外スタック・フレームのアドレスが格納される (VAXシステムのメカニズム・アレイにはこれに対応する引数はない)。
シグナル・アレイのアドレス Alphaシステムでは,この引数にはシグナル・アレイのアドレスが格納される (VAXシステムのメカニズム・アレイにはこれに対応する引数はない)。
レジスタ VAXシステムでもAlphaシステムでも, メカニズム・アレイにはスクラッチ・レジスタの内容が格納される。 Alphaシステムでは,この引数にはるかに大きなレジスタ・セットが格納され, 対応する浮動小数点レジスタも格納される。

対処方法

32ビット・シグナル・アレイはAlphaシステムとVAXシステムとで同じであるため, 条件処理ルーチンのソース・コードを変更する必要はないでしょう。しかし, メカニズム・アレイは変更されているため, ソース・コードを変更しなければならないかもしれません。特に, 次のことを確認してください。

例 8-1はCで作成した条件処理ルーチンを示しています。

例 8-1 条件処理ルーチン

     #include  <ssdef.h>
     #include  <chfdef.h>
        .
        .
        .
  【1】 int cond_handler( sigs, mechs )
        struct  chf$signal_array  *sigs;
        struct  chf$mech_array   *mechs;
     {
          int status;

  【2】   status = LIB$MATCH_COND(sigs->chf$l_sig_name, /* returned code */
                                  SS$_INTOVF);          /* test against  */

  【3】   if(status != 0)
          {
              /*  ...Condition matched.  Perform processing.  */
              return SS$_CONTINUE;
          }
          else
          {
              /*  ...Condition does not match. Resignal exception. */
              return SS$_RESIGNAL;
          }
     }

次のリストの各項目は 例 8-1に示した番号に対応しています。

【1】このルーチンは, システムがシグナル・アレイとメカニズム・アレイに戻すデータをアクセスするために, sigsとmechsという2つの引数を定義します。このルーチンは前もって定義されている 2つのデータ構造を使用して,引数を宣言します。2つのデータ構造とは chf$signal_arrayとchf$mech_arrayであり,システムによって CHFDEF.Hヘッダ・ファイルに定義されています。
【2】この条件処理ルーチンは LIB$MATCH_CONDランタイム・ライブラリ・ルーチンを使用することにより, 戻された条件コードと,整数オーバーフローを識別する条件コード (SSDEF.Hに定義されているコード)を比較します。 条件コードはシステム定義のシグナル・データ構造のフィールドとして参照されます (CHFDEF.Hに定義されています)。
【3】LIB$MATCH_CONDルーチンは, 一致する条件コードを検出したときにゼロ以外の結果を戻します。 条件処理ルーチンはこの結果をもとに,異なるコード・パスを実行します。


8.4 例外条件の識別

アプリケーションの条件処理ルーチンは, シグナル・アレイに戻された条件コードを確認することにより, どの例外が通知されているかを識別します。次のプログラムの一文は 例 8-1から抜粋したものであり, 条件処理ルーチンがランタイム・ライブラリ・ルーチン LIB$MATCH_CONDを使用することにより, この作業をどのような方法で実現できるかを示しています。

     status = LIB$MATCH_COND( sigs->chf$l_sig_name,  /* returned code */
                                       SS$_INTOVF);  /* test against  */

このメカニズムはAlphaシステムでも変更されていません。 32ビットの条件コードの形式とシグナル・アレイ内での位置は, VAXシステムの場合と同じです。しかし,条件処理ルーチンが VAXシステムで受け取っていた条件コードは Alphaシステムでは意味がないでしょう。アーキテクチャが異なるため, VAXシステムで戻されていた一部の例外条件は,Alphaシステムではサポートされません。

ソフトウェア例外の場合には,Alphaシステムは VAXシステムの場合と同じ例外をサポートします。このことについては, オンライン・ヘルプ・メッセージ・ユーティリティまたは 『OpenVMS system messages documentation』に示されています。しかし, ハードウェア例外はソフトウェア例外よりアーキテクチャに依存する部分が多く, 特に算術演算例外はアーキテクチャに依存しています。 VAXシステムでサポートされていたハードウェア例外の一部( 『OpenVMS Programming Concepts Manual』を参照)だけが Alphaシステムでもサポートされます。さらに,Alphaアーキテクチャでは, VAXアーキテクチャでサポートされないいくつかの追加された例外を定義しています。

表 8-1は,Alphaシステムでサポートされない VAXハードウェア例外と,VAXシステムでサポートされない Alphaハードウェア例外を示しています。アプリケーションの例外処理ルーチンがこれらの VAX固有の例外をテストする場合には,対応する Alpha例外をテストするためのコードを追加する必要があります( Alphaシステムでの算術演算例外のテストについての詳しい説明は, 第8.4.1項を参照してください)。


注意
Alphaシステムで実行されるトランスレートされたVAXイメージは,これらの VAX例外を戻すことができます。

表 8-1 アーキテクチャ固有のハードウェア例外 :(クリックで表示)


8.4.1 Alphaシステムでの算術演算例外のテスト

VAXシステムでは,アーキテクチャは算術演算例外が同期的に報告されるようにします。 つまり,例外(オーバーフローなど)の原因となったVAX算術演算命令は, ただちに例外処理ハンドラを開始し,後続の命令は実行されません。 例外ハンドラに報告されるプログラム・カウンタ(PC)は, 例外の原因となった算術演算命令のPCです。このため, アプリケーション・プログラムは,たとえば,メイン・シーケンスを再開し, 例外の原因となった操作を同等の操作または別の操作によってエミュレートするか, 置換することができます。

Alphaシステムでは,算術演算例外は非同期的に報告されます。つまり, アーキテクチャの実現方法により,例外の原因となった命令より後の多くの命令 (分岐やジャンプも含む)を実行できます。これらの命令は, 例外の原因となった命令が使用していたオペランドの上に重ね書きする可能性があるため, 例外を解釈したり,修正するのに必要な情報が失われてしまいます。 例外ハンドラに報告されるPCは,例外の原因となった命令のPCではなく, その後に実行された命令のPCです。 例外がアプリケーションの例外ハンドラに報告される時点では, ハンドラは入力データを修正しており, 命令を再起動することができない可能性があります。

このように,算術演算例外の報告方法が基本的に異なるため,Alphaシステムでは, SS$_HPARITHという1つの条件コードを定義し, これによってすべての算術演算例外を示します。たとえば, 整数オーバーフロー例外が発生したときに処理を実行する条件処理ルーチンがアプリケーションに含まれている場合, VAXシステムでは,SS$_INTOVR条件コードが例外処理ルーチンに渡されます。 Alphaシステムでは,この例外はSS$_HPARITHという条件コードによって示されます。 このため,アプリケーションの条件処理ルーチンは, Alpha算術演算例外を対応するVAX例外と誤って解釈することがありません。 処理を行うアプリケーションが,アーキテクチャ固有である可能性があるため, このことは重要です。

図 8-3は SS$_HPARITH例外シグナル・アレイの形式を示しています。

図 8-3 SS$_HPARITH例外シグナル・アレイ

このシグナル・アレイには,SS$_HPARITH例外の固有の3つの引数が格納されます。 それは整数レジスタ・ライト・マスク,浮動小数点レジスタ・ライト・マスク, および例外サマリです。整数および浮動小数点レジスタ・ライト・マスクは, 例外サマリのビットをセットした命令のターゲットであったレジスタを示します。 マスク内の各ビットはレジスタを表現します。例外サマリは最初の 7ビットにフラグをセットすることにより,通知される例外のタイプ( 1つ以上)を示します。表 8-2 はこれらの各ビットがセットされているときの意味を示しています。

表 8-2 例外サマリ引数のフィールド

ビット 意味
0 ソフトウェアは正常終了した。
1 浮動小数点演算,変換,または比較操作に誤りがある。
2 浮動小数点除算で0による除算を実行しようとした。 0による整数除算は報告されないので注意しなければならない。
3 浮動小数点演算または変換操作で宛先の指数部がオーバーフローした。
4 浮動小数点演算または変換操作で宛先の指数部がアンダーフローした。
5 浮動小数点演算または変換操作で正確な算術演算結果と異なる結果が報告された。
6 浮動小数点数値から整数への変換操作または整数算術演算で宛先の精度がオーバーフローした。

対処方法

算術演算例外に応答して処理を実行する条件処理ルーチンを Alphaシステムで実行するために変更しなければならないかどうかを判断する場合には, 次のガイドラインに従ってください。


8.4.2  データ・アラインメント・トラップのテスト

Alphaシステムでは,アラインされていないアドレスをオペランドとして受け付ける Alpha命令(LDQ_U)を使わずに, 自然なアラインメントになっていないアドレスを使用して, レジスタとの間でロングワードまたはクォドワードをロード/ストアしようとする操作を実行すると, データ・アラインメント・トラップが発生します (データ・アラインメントについての詳しい説明は, 第7章を参照してください)。

Alphaシステムのコンパイラは通常,次の操作を実行することにより, アラインメント・フォルトの発生を防止します。

しかし,動的に定義されるデータをコンパイラがアラインすることはできません。 したがってこのような場合は,アラインメント・フォルトが発生する可能性があります。

アラインメント例外は条件コードSS$_ALIGNによって示されます。 図 8-4は, SS$_ALIGN例外によって戻されるシグナル・アレイの要素を示しています。

図 8-4 SS$_ALIGN例外のシグナル・アレイ

このシグナル・アレイには,SS$_ALIGN例外固有の2つの引数が格納されます。 それは仮想アドレスとレジスタ番号です。仮想アドレスには, アクセスしているアラインされていないデータのアドレスが格納されます。 レジスタ番号は操作の対象となるレジスタを示します。

対処方法


8.5 条件処理に関連する他の作業の実行

いままでに述べてきた条件処理ルーチンの問題に加えて, 条件処理を含むアプリケーションは, システムに対して条件処理ルーチンを設定するなどの他の操作を実行しなければなりません。 ランタイム・ライブラリには, アプリケーションでこれらの操作を実行するためのルーチンが準備されています。 たとえば,アプリケーションでランタイム・ライブラリ・ルーチン LIB$ESTABLISHを呼び出すことにより, 例外が通知されるときに実行される条件処理ルーチンを識別(または設定)できます。

VAXアーキテクチャとAlphaアーキテクチャには相違点があり, 両方のアーキテクチャの呼び出し規則にも違いがあるため, これらの多くの操作の実現方法は同じではありません。 表 8-3は VAXシステムで提供されるランタイム・ライブラリ条件処理サポート・ルーチンと, Alphaシステムではどのルーチンがサポートされるかを示しています。

表 8-3 ランタイム・ライブラリ条件処理サポート・ルーチン :(クリックで表示)

対処方法

次のリストは, ランタイム・ライブラリ・ルーチンを使用するアプリケーションにおけるガイドラインを示しています。

たとえば,例 8-2に示したプログラムは FORTRANで作成されており,条件コードSS$_INTOVFを指定することにより, 整数オーバーフローをテストする条件処理ルーチンを指定するために, RTLルーチンLIB$ESTABLISHを使用しています。VAXシステムでは, 整数オーバーフローの検出を可能にするために,プログラムをコンパイルするときに /CHECK=OVERFLOW修飾子を指定しなければなりません。

このプログラムをAlphaシステムで実行するには,条件コードをSS$_INTOVFから SS$_HPARITHに変更しなければなりません (オーバーフローのタイプはシグナル・アレイ内の例外サマリ引数を調べることにより判断できます。 詳しくはコンパイラに関する解説書を参照してください)。VAXシステムの場合と同様に, オーバーフロー検出を可能にするためにはコンパイル・コマンド・ラインに /CHECK=OVERFLOW修飾子を指定なければなりません。DEC Fortranは LIB$ESTABLISHルーチンを組み込み関数として受け付けるため, このルーチンの呼び出しを削除する必要はありません。

例 8-2 条件処理プログラムの例

     C       This program types a maximum value of integers
     C       Compile with /CHECK=OVERFLOW and the /EXTEND_SOURCE qualifiers

             INTEGER*4 int4
             EXTERNAL HANDLER
             CALL LIB$ESTABLISH (HANDLER) 【1】

             int4=2147483645
             WRITE (6,*) ' Beginning DO LOOP, adding 1 to ', int4
             DO I=1,10
               int4=int4+1
               WRITE (6,*) ' INT*4 NUMBER IS  ', int4
             END DO
             WRITE (6,*) ' The end ...'
             END

     C       This is the condition-handling routine

             INTEGER*4 FUNCTION HANDLER (SIGARGS, MECHARGS)
             INTEGER*4 SIGARGS(*),MECHARGS(*)
             INCLUDE '($FORDEF)'
             INCLUDE '($SSDEF)'
             INTEGER INDEX
             INTEGER LIB$MATCH_COND

             INDEX = LIB$MATCH_COND (SIGARGS(2), SS$_INTOVF) 【2】
             IF (INDEX .EQ. 0 ) THEN
                HANDLER = SS$_RESIGNAL
             ELSE IF (INDEX .GT. 0) THEN
                WRITE (6,*) 'Arithmetic exception detected...'
                CALL LIB$STOP(SIGARGS(1))
             END IF
             END

次のリストの各項目は 例 8-2に示されている番号に対応しています。

【1】 この例では,条件処理ルーチンを指定するためにLIB$ESTABLISHを呼び出します。
【2】 Alphaシステムでは,条件コードをSS$_INTOVFから SS$_HPARITHに変更しなければなりません。条件処理ルーチンは LIB$STOPルーチンを呼び出すことにより,プログラムの実行を終了します。
次の例は,例 8-2に示したプログラム名をコンパイル, リンク,および実行する方法を示しています。

     $ FORTRAN/EXTEND_SOURCE/CHECK=OVERFLOW  HANDLER_EX.FOR
     $ LINK  HANDLER_EX
     $ RUN   HANDLER_EX
      Beginning DO LOOP, adding 1 to 2147483645
      INT*4 NUMBER IS    2147483646
      INT*4 NUMBER IS    2147483647
     Arithmetic exception detected...
     %TRACE-F-TRACEBACK, symbolic stack dump follows
      Image Name   Module Name     Routine Name    Line Number  rel PC      abs PC
      INT_OVR_HAND INT_OVR_HANDLER HANDLER                1637 00000238    00020238
      DEC$FORRTL                                             0 000651E4    001991E4
     ----- above condition handler called with exception 00000504:
     %SYSTEM-F-HPARITH, high performance arithmetic trap, Imask=00000001, Fmask=00000
     000, summary=40, PC=000200E0, PS=0000001B
     -SYSTEM-F-INTOVF, arithmetic trap, integer overflow at PC=000200E0, PS=0000001B
     ----- end of exception message
                                                            0 84FE9FFC    84FE9FFC
     INT_OVR_HAND INT_OVR_HANDLER INT_OVR_HANDLER          15 000000E0    000200E0
                                                            0 84EFD918    84EFD918
                                                            0 7FF23EE0    7FF23EE0


[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]