PCMPESTRI - Packed CoMPare Explicit STRing Index
PCMPESTRM - Packed CoMPare Explicit STRing Mask
PCMPISTRI - Packed CoMPare Implicit STRing Index
PCMPISTRM - Packed CoMPare Implicit STRing Mask

PCMPESTRI xmm1, xmm2/m128, imm8    (S4.2
VPCMPESTRI xmm1, xmm2/m128, imm8    (V1
int _mm_cmpestri (__m128i a, int la, __m128i b, int lb, const int imm8);
int _mm_cmpestr○ (__m128i a, int la, __m128i b, int lb, const int imm8);

PCMPESTRM xmm1, xmm2/m128, imm8    (S4.2
VPCMPESTRM xmm1, xmm2/m128, imm8    (V1
__m128i _mm_cmpestrm (__m128i a, int la, __m128i b, int lb, const int imm8);
int _mm_cmpestr○ (__m128i a, int la, __m128i b, int lb, const int imm8);
PCMPISTRI xmm1, xmm2/m128, imm8    (S4.2
VPCMPISTRI xmm1, xmm2/m128, imm8    (v1
int _mm_cmpistri (__m128i a, __m128i b, const int imm8);
int _mm_cmpistr○ (__m128i a, __m128i b, const int imm8);
PCMPISTRM xmm1, xmm2/m128, imm8    (S4.2
VPCMPISTRM xmm1, xmm2/m128, imm8    (V1
__m128i _mm_cmpistrm (__m128i a, __m128i b, const int imm8);
int _mm_cmpistr○ (__m128i a, __m128i b, const int imm8);

基本

命令の違いは基本的な機能の違いではなくデータの受け渡し方の違い。

ESTR* 文字列の長さを指定する
ISTR* NULで文字列の終端を表す

*STRI インデックスを返す
*STRM マスクを返す
*str○ ○=a/c/o/s/z フラグを戻り値として返す

何をするかはimm8のビット3:2で指定する。

imm8 bit3:2 モード 機能
00 Equal Any 文字(複数)が文字列に含まれるか調べる
01 Ranges 範囲内の文字(複数)が文字列に含まれるか調べる
10 Equal Each 文字列を比較する
11 Equal Ordered 文字列が文字列に含まれるか調べる

文字の形式はimm8のビット1:0で指定する。

imm8 bit1:0 文字の形式
00 符号なしBYTE
01 符号なしWORD
10 符号つきBYTE
11 符号つきWORD

文字列は下位側から指定文字数またはNULの直前までが有効データ、それより上位側は無効データとして扱われる。(下位側が文字列の頭)

ESTR*のバイト/ワード数は指定した値の絶対値が使われる。絶対値が16(BYTE)/8(WORD)より大きい場合は16/8として扱われる。

ISTR*ではNUL自身は無効データとして扱われる。NULがないときは16バイト/8ワード全部が有効データになる。

モードに応じてIntRes1(中間結果1)を生成

モード00: Equal Any - 文字(複数)が文字列に含まれるか調べる

モード01: Ranges - 範囲内の文字(複数)が文字列に含まれるか調べる

モード10: Equal Each - 文字列を比較する

モード11: Equal Ordered - 文字列が文字列に含まれるか調べる

得られたIntRes1(中間結果1)をIntRes2(中間結果2)に変換

16/8ビットのIntRes1の各ビットについて以下の操作を行いIntRes2を生成

imm8 bit5:4 名前 処理内容
00 Positive Polarity(+) IntRes1をそのままIntRes2にする
01 Negative Polarity(-) IntRes1を全ビット反転してIntRes2にする
10 Masked(+) IntRes1をそのままIntRes2にする
11 Masked(-) xmm2/m128 b 側のBYTE/WORDが
有効データならIntRes1の対応するビットを反転してIntRes2にする
無効データならIntRes1の対応するビットをそのままIntRes2にする

IntRes2(中間結果2)から戻り値を生成

*STRI命令はECX/RCXレジスタ(int型戻り値)にインデックス(0~15(BYTE)/0~7(WORD))を返す。立っているビットがないときは16/8が返される

imm8 bit6 返される値
0 IntRes2の一番右(LSB側)の立っているビットの番号
1 IntRes2の一番左(MSB側)の立っているビットの番号

*STRM命令はXMM0レジスタ(固定)(__m128i型戻り値)にIntRes2を返す

imm8 bit6 返される値
0 最下位16/8ビットにIntRes2を返す
1 IntRes2の各ビットをBYTE/WORD(全ビット0または全ビット1)に拡張して返す

フラグは以下のように設定される

CF 0 IntRes2が0
1 IntRes2が0以外
ZF 0 ②xmm2/m128 b がすべて有効データ
1 ②xmm2/m128 b に無効データが含まれる
SF 0 ①xmm1 a がすべて有効データ
1 ①xmm1 a に無効データが含まれる
OF IntRes2の最下位ビット
AF 0
PF 0

*str○はフラグの値(0または1)を返す。

*strc CF
*strz ZF
*strs SF
*stro OF
*stra (CF==0 && ZF==0)のとき1
それ以外のとき0を返す

imm8まとめ

bit   意味
1:0 文字タイプ 00 符号なしBYTE
01 符号なしWORD
10 符号つきBYTE
11 符号つきWORD
3:2 モード 00 Equal Any 文字(複数)が文字列に含まれるか調べる
01 Ranges 範囲内の文字(複数)が文字列に含まれるか調べる
10 Equal Each 文字列を比較する
11 Equal Ordered 文字列が文字列に含まれるか調べる
5:4 極性 00 Positive Polarity(+) IntRes1をそのままIntRes2にする
01 Negative Polarity(-) IntRes1を全ビット反転してIntRes2にする
10 Masked(+) IntRes1をそのままIntRes2にする
11 Masked(-) xmm2/m128 b 側のBYTE/WORDが
有効データならIntRes1の対応するビットを反転してIntRes2にする
無効データならIntRes1の対応するビットをそのままIntRes2にする
6 返す値 0 *STRI命令 最下位の立っているビット番号を返す
*STRM命令 ビットマスクを返す
1 *STRI命令 最上位の立っているビット番号を返す
*STRM命令 BYTE/WORDマスクを返す
7 未使用 0を指定

レジスタまとめ

以下のレジスタはオペランドでは指定しないが固定で使われる

レジスタ 命令 意味
EAX/RAX ESTR* (IN) オペランド1の長さ
EDX/RDX ESTR* (IN) オペランド2の長さ
ECX/RCX *STRI (OUT) インデックス
XMM0 *STRM (OUT) マスク

 


x86/x64 SIMD命令一覧表  フィードバック