えぐち@エスアンドイー です。

>>> On Tue, 2 Feb 1999 17:20:44 +0900, SHUDO Kazuyuki <shudoh / muraoka.info.waseda.ac.jp> said:

首藤> 首藤です。
...
首藤> > FPU のレジスタの値も、他のレジスタ同様コンテキスト
首藤> > スイッチで退去/復元されるものと理解していました。
首藤> 
首藤> 今 FreeBSD マシンにログインできないので、手もとの Linux 2.2.1 で
首藤> 実験したところ、あるプロセスでの変更は他プロセスに影響を与えません。
首藤> 当然ですね…
首藤> FreeBSD でも、FPU control word はプロセスのコンテクストに
首藤> 含まれると思います。

/usr/src/sys/i386/i386/swtch.s:cpu_switch がカーネル内部の
該当箇所です。...しっかりやっていました。

ちなみに、setjmp() のコンテキストは、_JBLEN == 8 で
{ AX, BX, CX, DX, EX, BP, SP, IP } の八本しか退去しません。

首藤> > そう考えると、main() の出口で戻しているのは、、なんか変!
首藤> 
首藤> 変ですね。
首藤> 何もプログラム終了時に FPU control word を元に戻す必要はないはずです。
首藤> 
首藤> FreeBSD の ports-jp ML に文章を書いた人の勘違いでしょうか。
首藤>   http://www.jp.freebsd.org/ports-jp/

C++ の場合の、 main() {} のスコープのインスタンスの
ディストラクタには間に合いそうですね ;-)

首藤> > > と言っても、floatingpoint.h で提供されるインタフェースが
首藤> > > x86 以外を考慮していないようなので(2.2.7R で確認)、
首藤> >
首藤> > man fpgetround(3) によると
首藤> >  HISTORY
首藤> >       These routines are based on SysV/386 routines of the same name.
首藤> 
首藤> > Solaris for x86 とかには、 fpsetmask() はあるのでしょうか?
首藤> 
首藤> 少なくとも Linux 2.2.1/x86 に fpsetmask(), fpgetround() はありません。

Linux って SysV との互換性が高いと聞いていたので以外ですね。
まぁ、fpsetmask(), fpgetround() などはユーザランドのコードなので
如何様にもなると言えばなりますが。。

首藤> > あるなら、初期状態でマスクは、どのような値なのでしょうか?
首藤> 
首藤> Linux では (以前書いたように) 0x37f です。
首藤> ところが、/usr/include/fpu_control.h (glibc 2.0.7) に
首藤> 以下の記述があります。
首藤> 
首藤>  * The hardware default is 0x037f. I choose 0x1372.
首藤> 
首藤> Linux では ハードウェアの初期値のままになっている、
首藤> ということでしょうか。

というか process を生成した時のプロセス構造体の初期値に
H/W の初期値を選んだと言う事ですね。

首藤> > x87 を使った UNIX に普遍的な問題なのでしょうか?
首藤> 
首藤> FreeBSD 以外にも、わざと一部の例外処理をマスクしていない OS が
首藤> あるかもしれないですね。
首藤> #NetBSD, OpenBSD なんかはその線が濃厚か?

こちらは、マシンと時間があったら調べて見ます。

首藤> ruby としては SIGFPE で終了してしまうのは困るわけで、
首藤> マスクしてしまうか、SIGFPU が起きないようなコードにするか、
首藤> の必要がありそうです。

基本的には、この間の main.c へのパッチで FreeBSD は
良い様だけれども、

	ruby -e 'p 1e300 / 1e-300'
	ruby -e 'p 1.0 % 0.0'

がいろいろなプラットホームで安全に 

	Inf と NaN 

を返すかを知りたいですね。

FreeBSD/i386 2.2.8 ....OK
FreeBSD/i386 2.2.8 ....OK
SunOS-4.1.4-JLE .......OK

でした。

首藤> x86 の FPU といえば、FPU 内で浮動小数点数を 64bit で扱う 
首藤> (FreeBSD)か 80bit で扱う (Linux) かの問題もあります。こ
首藤> れによって計算結果が変わり得るので。でもこれを言い出すと、
首藤> 異なる種類の FPU での計算結果は同じになるのか?という問
首藤> 題にぶつかります。

同じ FPU でも丸めモードが異なったりするだけで
かなりの違いが出ます。
特に近い値同士の引き算などは辛いです。

首藤> 最悪、プラットフォームが異なると ruby スクリプトの
首藤> 実行結果が異なる、という現象が起こり得ます。
首藤> 処理系依存を認めていた過去の言語では問題なかったけれど、
首藤> Java などでは…

言語処理系で問題が発覚するけど、つまるところ
マシンとOS(と広義のライブラリ)の問題な気もします。

Java での対応は私も気になります。

	えぐち