_mm_cmpistri
Classification
SSE_ALL, String Compare, CPUID Test: SSE4.2
Header File
nmmintrin.h
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