注:私がこの種の作業に取り組んでからしばらく経ちました。うまくいけば、私の答えは球場にあります。
これが発生したときに発生するdiv-0例外をトラップする必要がMSR.FE0
あります。これを希望MSR.FE1
どおりFPSCR.VE
にFPSCR.ZE
処理できるようにするには、操作する必要があります。
したがって、その設定と動作を開始したら、次のことを行う必要があります。
これらのシナリオ(0/0および1/0)の例外処理を制御します。私が使用しているほとんどの小さなリアルタイムカーネルでは、すべてのソースコードが利用可能であるため、何をすべきかがわかります。RTOSが何であるか、またはどの程度の制御が可能かわからない。「より重い」OSの場合、例外ハンドラロジックをいじることができない可能性があります。0/0
「無効な操作」例外(FPSCR.VE
)をトリガーするのに対し1/0
、IEEE浮動小数点ゼロ除算例外( )をトリガーすると思いますFPSCR.ZE
。
無効な操作の例外が発生した場合は、原因が0/0
何か他のものであるかどうかを判断する必要があります。で0/0
、FPSCR.VXZDZ
設定されます(私は思います)。この例外をトリガーする方法は他にもあるので、ここFPSCR
にあなたの友達がいます。
IEEE FP div-0例外が発生した場合は、原因が1/0
何か他のものであるかどうかを判断する必要があります(例2/0
)。1
このためには、中断されたコンテキストのレジスタを調べて、分子が例外の原因となった除算操作の時点であったかどうかを確認する必要があると思います。1/0
FPUは、あなたが試みたかどうかを気にしません2/0
が、明らかにあなたのアプリケーションは気にします。
次に、目的の結果が得られるように、返されるコンテキストを変更する必要があります。これは、操作で使用されるFPレジスタを変更して、例外から戻ったときにFP除算が再試行されたときに、ゼロになるようにするようなものです。たとえば、分子0
と除数を作成し1
ます。
その後、例外から戻ると、目的の結果が得られるはずです。申し訳ありませんが、特定のレジスタと値に錆びています。これで作業を完了するのに十分だと思います。
また、アプリケーションプロセスのためだけにこの動作を選択的に有効にすることについても質問しました。以前はこのようなことをしなければなりませんでしたが、フラットアドレス空間の「シングルプロセス、マルチスレッド」タイプのカーネル(各タスクは実際にはスレッドであり、すべて同じフラットアドレス空間で実行されます)です。私はそれをいくつかの異なる方法で行いました、ここにあなたのために働くかもしれないいくつかのアイデアがあります:
例外ハンドラーで、プロセスID /タスクIDを調べ、それがアプリケーションプロセスの場合は特別な方法で処理し、そうでない場合は標準の「システム」の方法で処理します。
または、アプリケーションへのコンテキストスイッチで、この例外の「特別な」処理をインストールします。アプリケーションプロセスからのコンテキストスイッチで、標準の処理に置き換えます。アプリケーション自体はこれを実行できないことに注意してください。実行するにはカーネルを利用する必要があります(使用できるコンテキストスイッチフック/コールアウトがある場合があります。そうでない場合は、カーネルソースを変更する可能性があります。 )。
私は以前にこのようなレガシーコードを継承しましたが、あなたの苦痛を感じます。あなたはそのような骨頭の振る舞いをインストールした人々にあなたの拳を振りたいです、しかし今あなたの拳を振ることはあなたが製品を出荷するのを助けません。解決策が必要です。幸運を。