_mm_cmpestra
Classification
SSE_ALL, String Compare, CPUID Test: SSE4.2
Header File
nmmintrin.h
Instruction
PCMPESTRI xmm, xmm, imm8
Synopsis
 _mm_cmpestra(__m128i a, int la, __m128i b, int lb, const int imm8);
Description
Compare packed strings in "a" and "b" with lengths "la" and "lb" using the control in "imm8", and returns 1 if "b" did not contain a null character and the resulting mask was zero, and 0 otherwise. [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 i == la
			aInvalid := 1
		FI
		IF j == lb
			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
FOR i := 0 to UpperBound
	IF imm8[4]
		IF imm8[5] // only negate valid
			IF i >= lb // 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
dst := (IntRes2 == 0) AND (lb > UpperBound)