あ、なんか微妙に必要になってしまった。マニュアル見ればなんとかなるレベルだが、あれを正しく理解できている自信が無い。
でも、あと半年でSandyBridge出るのに今Nehalem買おうという気にはならんなー。あとCeleronがNehalemだとか言ったやつ誰だ出てこい。
さて、SSE4.2の文字列比較命令は、RISC時代が終わったとは言え、現代でもこういう命令が生まれるのかと感心する程度に複雑な命令だと思う。pcmpistr命令は即値まで含めると、5つものオペランドをとる。転送命令以外でこれほどのオペランドをとる命令は歴史的に見ても珍しいのではないかと思う。
pcmpistri, pcmpistrm, pcmpestri, pcmpstrm は、文字列処理のための命令である。それぞれの命令の処理内容はほぼ同じで、違うのは、出力がecxに出るかxmm0に出るかどうか、および、0終端文字列か、長さ付きの文字列かどうか、の二点である。
出力先 | 終端 | |
pcmpestri | ecx | 長さ |
pcmpestrm | xmm0 | 長さ |
pcmpistri | ecx | '\0' |
pcmpistrm | xmm0 | '\0' |
5文字目の(i|e)が、(Implicit length|Explicit length)をあらわし、最後の(i|m)が(return Index|return Mask)をあらわす。
アセンブリの表記上は、2つのxmmレジスタと、1個の8bit即値をとる。
PCMPxSTRx xmm1, xmm2/m128, imm8
Explicit Lengthのほうは、これに加えて、eax, ecxを暗黙のオペランドにとり、それぞれ1個目のオペランド, 2個目のオペランドの長さをあらわす。
imm8即値は、この命令の挙動を制御する。この即値オペランドによって挙動がかなり変わる。PCMPxSTRxは一個の命令のように見えるが、これを一個の命令と呼んでいいのか疑問。即値まで含めて命令オペコードなんじゃないか?という気がしてくる。
この即値で制御できる挙動は、以下の4点である。
- Source data format(0,1bit目) : 文字サイズが1byteか2byteか。signed か unsigned か。
- Aggregation Operation(2,3bit目) : どういう比較をするか。
- Polarity(4,5bit目) : 中間結果を反転するかどうか(真偽値を逆転するかどうか)
- OutputSelection(6bit目,return Indexの場合) : 中間結果に対してclzするかctzするか
- OutputSelection(6bit目,return Maskの場合) : 中間結果ビット列をバイト列に拡張するか
まずSource data format。特に説明はいらないと思う。Aggregation Operationで数値の範囲を比較する操作があるので、符号の有無で挙動が変わる。
次にAggregation Operation。これで挙動が大分変わる。
概要は http://journal.mycom.co.jp/articles/2008/04/10/idf09/008.html の http://journal.mycom.co.jp/photo/articles/2008/04/10/idf09/images/Photo46l.jpg を見たほうがよい。詳細は intel の命令マニュアルを見たほうがいい。
どういう使いかたが想定されているかについては、intelの最適化マニュアルに書いてある。
次Polarity。比較結果はビット列になるのだが、これを反転するかどうかを決める。return Indexの場合は、立ってるビットの位置を探すのだが、この時ビット反転してあると、「等しい文字を探す」「等しくない文字を探す」というように挙動が変えられる。空白や改行文字を飛ばすとかしたい時に、反転したいものである。
最後OutputSelection。return IndexとreturnMaskの場合で意味が変わって、
- return Indexの場合は、立ってるビットのうちLSBを探すか、MSBを探すかを決める。
- return Maskの場合は、16bit もしくは 8 bitの結果を、そのままXMM0に入れるか、それとも16byteに拡張してXMM0に入れるかを決める。
となる。
さて、では、これを使って実際の処理がどうなるか見てみよう。と思ったが実機が無いので無理だった。