_mm_cmpistri
Classification
SSE_ALL, String Compare, CPUID Test: SSE4.2
Header File
Instruction
PCMPISTRI xmm, xmm, imm8
Synopsis
_mm_cmpistri(__m128i a, __m128i b, const int imm8);
Description
Compare packed strings with implicit lengths in "a" and "b" using the control in "imm8", and store the generated index in "dst".
[strcmp_note]
Operation
size := (imm8[0] ? 16 : 8) // 8 or 16-bit characters
UpperBound := (128 / size) - 1
BoolRes := 0
// compare all characters
aInvalid := 0
bInvalid := 0
FOR i := 0 to UpperBound
m := i*size
FOR j := 0 to UpperBound
n := j*size
BoolRes.word[i].bit[j] := (a[m+size-1:m] == b[n+size-1:n]) ? 1 : 0
// invalidate characters after EOS
IF a[m+size-1:m] == 0
aInvalid := 1
FI
IF b[n+size-1:n] == 0
bInvalid := 1
FI
// override comparisons for invalid characters
CASE (imm8[3:2]) OF
0: // equal any
IF (!aInvalid && bInvalid)
BoolRes.word[i].bit[j] := 0
ELSE IF (aInvalid && !bInvalid)
BoolRes.word[i].bit[j] := 0
ELSE IF (aInvalid && bInvalid)
BoolRes.word[i].bit[j] := 0
FI
1: // ranges
IF (!aInvalid && bInvalid)
BoolRes.word[i].bit[j] := 0
ELSE IF (aInvalid && !bInvalid)
BoolRes.word[i].bit[j] := 0
ELSE IF (aInvalid && bInvalid)
BoolRes.word[i].bit[j] := 0
FI
2: // equal each
IF (!aInvalid && bInvalid)
BoolRes.word[i].bit[j] := 0
ELSE IF (aInvalid && !bInvalid)
BoolRes.word[i].bit[j] := 0
ELSE IF (aInvalid && bInvalid)
BoolRes.word[i].bit[j] := 1
FI
3: // equal ordered
IF (!aInvalid && bInvalid)
BoolRes.word[i].bit[j] := 0
ELSE IF (aInvalid && !bInvalid)
BoolRes.word[i].bit[j] := 1
ELSE IF (aInvalid && bInvalid)
BoolRes.word[i].bit[j] := 1
FI
ESAC
ENDFOR
ENDFOR
// aggregate results
CASE (imm8[3:2]) OF
0: // equal any
IntRes1 := 0
FOR i := 0 to UpperBound
FOR j := 0 to UpperBound
IntRes1[i] := IntRes1[i] OR BoolRes.word[i].bit[j]
ENDFOR
ENDFOR
1: // ranges
IntRes1 := 0
FOR i := 0 to UpperBound
FOR j := 0 to UpperBound
IntRes1[i] := IntRes1[i] OR (BoolRes.word[i].bit[j] AND BoolRes.word[i].bit[j+1])
j += 2
ENDFOR
ENDFOR
2: // equal each
IntRes1 := 0
FOR i := 0 to UpperBound
IntRes1[i] := BoolRes.word[i].bit[i]
ENDFOR
3: // equal ordered
IntRes1 := (imm8[0] ? 0xFF : 0xFFFF)
FOR i := 0 to UpperBound
k := i
FOR j := 0 to UpperBound-i
IntRes1[i] := IntRes1[i] AND BoolRes.word[k].bit[j]
k := k+1
ENDFOR
ENDFOR
ESAC
// optionally negate results
bInvalid := 0
FOR i := 0 to UpperBound
IF imm8[4]
IF imm8[5] // only negate valid
IF b[n+size-1:n] == 0
bInvalid := 1
FI
IF bInvalid // invalid, don't negate
IntRes2[i] := IntRes1[i]
ELSE // valid, negate
IntRes2[i] := -1 XOR IntRes1[i]
FI
ELSE // negate all
IntRes2[i] := -1 XOR IntRes1[i]
FI
ELSE // don't negate
IntRes2[i] := IntRes1[i]
FI
ENDFOR
// output
IF imm8[6] // most significant bit
tmp := UpperBound
dst := tmp
DO WHILE ((tmp >= 0) AND a[tmp] == 0)
tmp := tmp - 1
dst := tmp
OD
ELSE // least significant bit
tmp := 0
dst := tmp
DO WHILE ((tmp <= UpperBound) AND a[tmp] == 0)
tmp := tmp + 1
dst := tmp
OD
FI