背景
- _mm_min_ps, _mm_max_ps を使っているコードを, ARM NEON に移植したい
- グラフィック関係なので, NaN, -0.0, 0.0 などの振る舞いをきちんと扱う必要がある.
SSE2 の minps, maxps と, NEON の vminq_f32, vmaxq_f32(ARMv7 NEON からある) および vminnmq_f32, vnmaxnmq_f32(ARMv8 で利用可能) には互換性がありません.
情報
minps, maxps
IEEE754-2008 相当(?)です.
両方 0.0(符号は問わない)の場合は, 第二ソースを返す.
第一ソースが NaN(quet, signaling) だと第二ソースを返す.
第二ソースが sNaN の場合, sNaN を返す.
(第二ソースが qNaN の場合, qNaN を返す)
それ以外: min(a, b)
ARM NEON
arm neon の vminq_f32, vmaxq_f32 は, どちらかが NaN だと NaN を返す.
vminnmq_f32, vmaxnmq_f32 だと, どちらかが NaN だと他方のソースを返すが, signaling NaN の場合は sNaN を返す.
-0.0, 0.0 については, 小さい(大きい)ほうを返す. つまり vmin の場合は -0.0 を返す.
-0.0, 0.0 の判定と, NaN の判定を両方うまくやるのは難しい感じです.
とりあえず以下のようになりました.
Max
同様にして, _mm_max_ps を実装します.
その他
SSE2 minps,maxps は, コンパイラなどで対応するときによかったですが,
最近ですと, あまりこの振る舞いは推奨されず, 今後の仕様(IEEE-754 201x?)からは削除(ふるまいが変わる)されました.
本来ですと, _mm_min_ps, _mm_max_ps を使っているコードを書きなおすのが望まれます.
(AVX あたりに新しい仕様にしたがった min/max 実装があったような?)