IA-32 インテル ®
8.1.2. x87 FPU ステータス・レジスタ
表8-1.に示すように、C1条件コード・フラグは各種の機能で使用される。x87 FPUステータス・ワー ド内のIEフラグとSFフラグがともにセットされている(スタックのオーバーフロー例外またはアン ダーフロー例外(#IS)を示す)場合は、C1フラグでオーバーフロー(C1=1)かアンダーフロー
(C1=0)のいずれであるかを識別する。ステータス・ワード内のPEフラグがセットされている(結 果が丸められて不正確であることを示す)場合は、命令による最後の丸めが切り上げであった場合 にC1フラグが1にセットされる。C1は、FXAM命令によって、現在チェックされている値の符号に 設定される。
C2条件コード・フラグは、FPREM命令とFPREM1命令が剰余計算の未完了(部分剰余)を示すため に使用する。剰余計算が正常に完了している場合は、C0、C3、およびC1の各条件コード・フラグが それぞれ、商の3つの最下位ビット(Q2、Q1、およびQ0)に対してセットされる。これらの命令が 条件コード・フラグを使用する方法については、『IA-32 インテル®アーキテクチャ・ソフトウェア・
デベロッパーズ・マニュアル、中巻』の第3章「命令セット・リファレンス」にある「FPREM1 − Partial Remainder」を参照のこと。
FPTAN、FSIN、FCOS、およびFSINCOSの各命令は、ソース・オペランドが許容範囲である±263を 超えたことを示す場合にC2フラグを1にセットし、ソース・オペランドが許容範囲内の場合は、C2 フラグをクリアする。
表8-1.で条件コード・フラグのステートが「未定義」と記されている場合は、それらのフラグのど の特定値にも依存してはならない。
8.1.2.3. x87 FPU浮動小数点例外フラグ
x87 FPUステータス・ワードの6つのx87 FPU浮動小数点例外フラグ(ビット0〜5)は、これらの
ビットが最後にクリアされてから1つ以上の浮動小数点例外が検出されたことを示す。個々の例外フ ラグ(IE、DE、ZE、OE、UE、およびPE)については、8.4.節「x87 FPU浮動小数点例外処理」で詳 しく説明する。それぞれの例外フラグは、x87 FPU制御ワードの例外マスク・ビットでマスクできる
(8.1.4.項「x87 FPU制御ワード」を参照)。マスクされていない例外フラグのいずれかがセットされ ると、例外サマリ・ステータス(ES)フラグ(ビット7)がセットされる。ESフラグがセットされ ると、8.7.節「ソフトウェア内でのx87 FPU例外の処理」で説明する技法のいずれかを使用してx87 FPU例外ハンドラが呼び出される。(例外フラグがマスクされている場合、そのフラグに関連付けら れている例外が発生すると、x87 FPUはそのフラグをセットするがESフラグはセットしないので注 意すること。)
例外フラグは、「スティッキー(頑固)」なビットである。すなわち、いったんセットされると、明 示的にクリアされるまではセットされたままになる。例外フラグをクリアするには、
FCLEX/FNCLEX(Clear exceptions)命令を実行する、FINIT/FNINIT命令かFSAVE/FNSAVE命令を 使用してx87 FPUを再初期化する、FRSTOR命令かFLDENV命令を使用してフラグを上書きする、
のいずれかの方法を用いる。
Bビット(ビット15)は、8087との互換性を得るためだけに含まれている。このビットは、ESフラ グの内容を反映する。
8.1.2.4. スタック・フォルト・フラグ
スタック・フォルト・フラグ(x87 FPUステータス・ワードのビット6)は、x87 FPUデータ・レジス タ・スタック内のデータに、スタック・オーバーフローまたはスタック・アンダーフローが発生した ことを示す。x87 FPUは、スタックのオーバーフロー条件またはアンダーフロー条件を検出した場合 にこのSFフラグを明示的にセットするが、無効演算オペランド条件を検出した場合には、SFフラグ を明示的にはクリアしない。このフラグがセットされている場合は、フォルトの性質は条件コード・
フラグC1が示す(すなわち、C1 =1であればオーバーフロー、C1 = 0であればアンダーフロー)。SF フラグは「スティッキー」なフラグであり、いったんセットされると、FINIT/FNINIT、FCLEX/FNCLEX、
FSAVE/FNSAVEなどの命令で明示的にクリアしない限り、プロセッサがこのフラグをクリアすること
はない。
表8-1. 条件コードの解釈
命令 C0 C3 C2 C1
FCOM, FCOMP, FCOMPP, FICOM, FICOMP, FTST, FUCOM, FUCOMP, FUCOMPP
比較の結果 オペランドが比 較できない
0 または #IS
FCOMI, FCOMIP, FUCOMI, FUCOMIP
未定義。(これらの命令はEFLAGSレジの ステータス・フラグをセットする。)
#IS
FXAM オペランド・クラス 符号
FPREM, FPREM1 Q2 Q1 0=余剰計算完了
1=余剰計算未完了
Q0 または #IS F2XM1, FADD, FADDP, FBSTP,
FCMOVcc, FIADD, FDIV, FDIVP, FDIVR, FDIVRP, FIDIV, FIDIVR, FIMUL, FIST, FISTP, FISUB, FISUBR,FMUL, FMULP, FPATAN, FRNDINT, FSCALE, FST, FSTP, FSUB, FSUBP, FSUBR, FSUBRP, FSQRT, FYL2X, FYL2XP1
未定義 切り上げまたは
#IS
FCOS, FSIN, FSINCOS, FPTAN 未定義 0=ソース・オペ
ランドが範囲内 1=ソース・オペ ランドが範囲外
切り上げまたは
#IS (C2=1の場 合は未定義) FABS, FBLD, FCHS, FDECSTP,
FILD, FINCSTP, FLD, Load Constants, FSTP (ext. real), FXCH, FXTRACT
未定義 0 または#IS
FLDENV, FRSTOR メモリからロードされた各ビット
FFREE, FLDCW, FCLEX/FNCLEX, FNOP, FSTCW/FNSTCW, FSTENV/FNSTENV, FSTSW/FNSTSW
未定義
FINIT/FNINIT, FSAVE/FNSAVE 0 0 0 0
x87 FPUスタック・フォルトの詳細については、8.1.6.項「x87 FPUタグ・ワード」を参照のこと。
8.1.3. 条件コードに基づく分岐と条件付き移動
P6ファミリ・プロセッサ以降のx87 FPUでは、2つの浮動小数点値の比較結果を基づいて、分岐や条 件付き移動を実行するためのメカニズムが2つ用意されている。本書では、これらのメカニズムを
「旧メカニズム」と「新メカニズム」と呼ぶ。
旧メカニズムは、Pentium Proプロセッサより前のx87 FPUとP6ファミリ・プロセッサで利用できる。
このメカニズムは、浮動小数点比較命令(FCOM、FCOMP、FCOMPP、FTST、FUCOMPP、FICOM、
およびFICOMP)を使用して2つの浮動小数点値を比較し、その結果に従って条件コード・フラグ
(C0〜C3)を設定する。次に、条件コード・フラグの内容を、次に挙げる2ステップの処理(図8-5.
を参照)によってEFLAGSレジスタのステータス・フラグにコピーする。
1. FSTSW AX 命令で、x87 FPUステータス・ワードをAXレジスタに移動する。
2. SAHF命令で、AXレジスタの上位8ビット(条件コード・フラグが含まれる)をEFLAGSレジ スタの下位8ビットにコピーする。
条件コード・フラグをEFLAGSレジスタにロードした後は、EFLAGSレジスタ内のステータス・フ ラグの新しい設定に基づいて、条件付きジャンプや条件付き移動が実行できる。
図8-5. 条件コードのEFLAGSレジスタへの移動
0 コード条件 ステータス・
フラグ C0
C1 C2 C3
CF
(なし)
PF ZF
C 1 F P F Z
F 7
31 EFLAGSレジスタ
0 C
2 C 1 C
3
AXレジスタ 0 C 15
0 C
2 C 1 C
3
x87 FPUステータス・ワード 0
C 15
FSTSW AX命令
SAHF命令
新メカニズムは、P6ファミリ・プロセッサでしか使用できない。このメカニズムでは、新しい浮動 小数点比較命令とEFLAGS設定命令(FCOMI、FCOMIP、FUCOMI、およびFUCOMIP)を使用して 2つの浮動小数点値を比較し、EFLAGSレジスタのZF、PF、およびCFフラグを直接設定する。この メカニズムでは、旧メカニズムで必要だった3つの命令を1つの命令に置き換えることができる。
また、P6ファミリ・プロセッサで新たに導入されたFCMOVcc命令を使用しても、EFLAGSレジス タのステータス・フラグ(ZF、PF、およびCF)の設定に基づいて浮動小数点値(x87 FPUデータ・
レジスタの値)の条件付き移動ができるので注意すること。これらの命令を使用すれば、浮動小数 点値の条件付き移動を実行する際にIFステートメントが不要になる。
8.1.4. x87 FPU制御ワード
16ビットのx87 FPU制御ワード(図8-6.を参照)は、使用するx87 FPUの精度と丸めの方法を制御す
るためのものである。このワードはまた、x87 FPU浮動小数点例外マスク・ビットも格納する。x87 FPU制御ワードは、x87 FPU制御レジスタにキャッシュされる。x87 FPU制御レジスタの内容は、
FLDCW命令を使用してロードし、FSTCW/FNSTCW命令を使用してメモリに格納できる。
FINIT/FNINITかFSAVE/FNSAVEFPUのいずれかの命令を使用してx87 FPUを初期化すると、x87 FPU 制御ワードは037FHに設定される。この場合、すべての浮動小数点例外がマスクされ、丸めモード は最近値に設定され、x87 FPUの精度は64ビットに設定される。
図8-6. x87 FPU制御ワード
15141312 11 10 9 8 7 6 5 4 3 2 1 0
X I
M P
M O M U M
Z M
D RC PC M
無限制御 丸め制御 精度制御
例外マスク 精度
アンダーフロー ゼロによる除算 デノーマル・オペランド 無効な動作
予約 オーバーフロー
8.1.4.1. x87 FPU浮動小数点例外フラグ・マスク
例外フラグ・マスク・ビット(x87 FPU制御ワードのビット0〜5)は、x87 FPUステータス・ワー ドの6つの浮動小数点例外フラグをマスクする。これらのマスク・ビットのいずれかがセットされる と、それに対応するx87 FPU浮動小数点例外の生成が阻止される。
8.1.4.2. 精度制御フィールド
精度制御(PC)フィールド(x87 FPU制御ワードのビット8〜9)は、x87 FPUが行う浮動小数点計 算の精度(64ビット、53ビット、または24ビット)を決定する(表8-2.を参照)。デフォルトの精 度は、拡張倍精度である。デフォルトの精度は拡張精度である。この精度では、x87 FPUデータ・レ ジスタの拡張倍精度浮動小数点フォーマットで使用可能なフル64ビットの仮数部が使用される。こ の設定にすれば、アプリケーションは、x87 FPUデータ・レジスタで可能な最大の精度をフルに利用 できる。したがって、この設定は、ほとんどのアプリケーションに最適である。
注:
* 暗黙の整数ビットを含む。
倍精度や単精度の設定では、仮数部のサイズがそれぞれ53ビットと24ビットに縮小される。これら の設定が用意されているのは、IEEE規格をサポートするとともに、低い精度のデータ型を使用して 行われていた計算を正確に再現できるようにするためである。これらの設定を使用すると、拡張倍 精度浮動小数点フォーマットが持つ64ビット長の仮数部ならではのメリットは失われる。低い精度 を指定した場合、仮数部の値の丸めによって、右側の使用されないビットがゼロにクリアされる。
精度制御ビットは、FADD、FADDP、FIADD、FSUB、FSUBP、FISUB、FSUBR、FSUBRP、FISUBR、
FMUL、FMULP、FIMUL、FDIV、FDIVP、FIDIV、FDIVR、FDIVRP、FIDIVR、およびFSQRTの各 浮動小数点命令の結果に対してのみ有効である。
8.1.4.3. 丸め制御フィールド
x87 FPU制御レジスタの丸め制御(RC)フィールド(ビット10〜11)は、x87 FPU浮動小数点命令
の結果を丸める方法を制御する。浮動小数点値の丸めについては、4.8.4.項「丸め」を参照のこと。
RCフィールドのエンコーディングについては、4.8.4.1.項「丸め制御(RC)フィールド」を参照のこと。
表8-2. 精度制御フィールド(PC)
精度 PCフィールド
単精度(24-Bits*) 00B
予約 01B
倍精度 (53-Bits*) 10B
拡張倍精度 (64-Bits) 11B