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