SSEを用いたbsr/bsf命令の実現に向けて その4

この_mm_cvtepi32_ps命令によって、

bit127 : 符号
bit126から8bit : bit96〜bit126の1が立っていたbit位置…(a)
bit95 : 符号
bit94から8bit : bit64〜bit125の1が立っていたbit位置…(b)
bit63 : 符号
bit62から8bit : bit32〜bit62の1が立っていたbit位置…(c)
bit31 : 符号
bit30から8bit : bit0〜bit31の1が立っていたbit位置…(d)

という変換が出来ます。


_mm_cvtepi32_ps命令は、s32(符号付き32bit整数)をfloatに変換する命令なので、s32のMSB(最上位ビット)は符号として反映されます。ゆえに、bsr/bsf目的では、このMSBまでは使えません。なお、u32(符号なし32bit整数)をfloatに変換する命令はSSEには存在しません。コメントでいただいていた「unsigned intからfloatへの変換があれば扱いやすいのですが」というのは、そういう意味です。


しかしBonanzaのBitboardは将棋盤の3段ずつu32に収められているため、3段☓9筋 = 27bitずつしか使われていませんので、やや使いにくいものの、これでも問題はありません。



変換後の(b),(c),(d)にさきほど見たように0x81を加算すればいいのでしょうか?
いえ違います。(c)は、27が加算された値、(b)は54(27*2)が加算された値が返ってきて欲しいです。


よって次のようになります。

  Bitboard_Cvt(bb,b1);

  bb >>= 7;
  bb += (u128)0xB70000009C000000810000;
  //  0x81 + 27 = 0x9c , 0x81 + 27*2 = 0xB7


いよいよ、見えてきましたね!!右に7ビットシフトしているのは左に1ビットシフトしても良さそうですが、それですと、最終的にpacked u16とみそうとしたときに変な位置に(b),(c),(d)が来てしまいます。右に7ビットシフトしているのは、このあとpacked u16としてみなしたいからですね。


ああ、ここに出てきた右シフトと加算はSSEの命令を使ってやっていると考えてください。


つづく