SSE3命令のひとつとしてFISTTP
(Store Integer and Pop from x87-FP with Truncation)が追加された.
以前からx87には“FISTP
”および“FIST
”(Store Integer)という浮動小数→整数変換命令があったが,
これらの命令では浮動小数から整数への変換を行う過程で
浮動小数点演算ユニット(FPU)内の“丸めモード”(Round Mode)ビットの状態に依存した丸め処理が適用されるようになっていた.
つまり,簡単にいえば,1.5という小数を整数に変換するときに,2とするか1とするかは丸めモードビットの状態がどうなっているかに依存するようになっていた.
これに対してSSE3で追加された新しい命令“FISTTP
”は
丸めモードが何になっているかとは無関係に常に小数点以下を切り捨てる動作になる.
FIST
/FISTTP
でも丸めモードに
“ゼロ方向への丸め”(Round toward Zero)=通称“切捨て”(Truncation)を設定していれば
切捨て丸めにすることができる.
ただ,この方法では,同じプログラムを構成するモジュールの中に異なる丸め方法を期待するものが混在している場合に
丸めモードを頻繁に変更しないといけなくなるし,
丸めモードを変更して戻し忘れる(あるいは割り込みが発生した場合などにもどすタイミングが失われる)と
他のモジュールの計算結果に影響が出てしまうなど,面倒なことになりやすい.
FISTTP
のように丸めモードを変更せずに切捨てにする命令があれば
他のモジュールへの影響を考慮しなくてよくなり,プログラミングが容易になる.
次のプログラムは
浮動小数の5.5(10)(倍精度浮動小数の16進数表現で40B00000H
)を
FISTP
命令とFISTTP
命令で整数に変換した結果を表示する例.
FPUの丸めモードにしたがった丸め処理を施すFISTP
命令を使うと5.5→6になるけど,
常に切り捨てにするFISTTP
命令では5.5→5になることがわかる.
.586 .model flat extern _printf: near .data fmtd db "%d" db 0aH db 00H f dword 40B00000H dst dword 00000000H .code _main proc public push ebp mov ebp, esp fld dword ptr f fistp dword ptr dst mov eax, dword ptr dst push eax push offset fmtd call _printf add esp, 8 fld dword ptr f fisttp dword ptr dst mov eax, dword ptr dst push eax push offset fmtd call _printf add esp, 8 mov eax, 0 pop ebp ret _main endp end