---
# System prepended metadata

title: Notes on how the sse4.2 string search functions

---


# Notes on how the sse4.2 string search functions

The most important thing is the immediate control value which determines how the rest of the arguments are used.

## String Data Type (pick only 1)

This determines what data type a "char" is for this operation:

* `_SIDD_UBYTE_OPS`: unsigned 8-bit characters (`u8`)
* `_SIDD_UWORD_OPS`: unsigned 16-bit characters (`u16`)
* `_SIDD_SBYTE_OPS`: signed 8-bit characters (`i8`)
* `_SIDD_SWORD_OPS`: signed 16-bit characters (`i16`)

## Comparison Operation (pick only 1)

Remembering that "chars" is the data type selected above...

* `_SIDD_CMP_EQUAL_ANY`: are any chars in `arg2` present anywhere in `arg1`
  * eg: [b'a', ...] searches for an 'a' anywhere in the string.
* `_SIDD_CMP_RANGES`: This makes `arg2` count as low bound and upper bound pairs that designate ranges to check for.
  * eg: [b'a', b'z', ...] would check `arg1` for chars in the b'a' to b'z' range
* `_SIDD_CMP_EQUAL_EACH`: is each char in `arg2` the same as the same position in `arg1`
  * eg: [b'a', b'b', ...] only matches "ab...". This is a "normal" style of string comparison
* `_SIDD_CMP_EQUAL_ORDERED`: Is `arg2` contained within `arg1`
  * eg: "bc" is a substring of "abcd"

## Operation Modifiers

You can negate the output, which effectively tests for the opposite thing:
* `_SIDD_NEGATIVE_POLARITY` will negate all results.
* `_SIDD_MASKED_NEGATIVE_POLARITY` will negate results "in the string" only.

With operations that end in `i` you can pick the index you get:
* `_SIDD_LEAST_SIGNIFICANT`: least significant bit (this is default)
* `_SIDD_MOST_SIGNIFICANT`: most significant bit

With operations that end in `m` you can pick the mask you get:
* `_SIDD_BIT_MASK`: return bit mask (this is default)
* `_SIDD_UNIT_MASK`: return byte/word mask (depending on char size)

(The second two selections are `imm8[6]`, in the pseudocode on the Intel Intrinsics Guide)

## The Actual Functions To Call

All the functions are named like `cmp?str?`:
* The first unknown is how the string length is known:
  * `i`: for "implicit string length" (null-terminated).
  * `e`: for "explicit string length" (an extra int arg passed after each register arg).
* The second unknown is one of [a,c,i,m,o,s,z]
  * `a`: returns 1 if b did not contain a null character and the resulting mask was zero, and 0 otherwise.
      * ??
  * `c`: returns 1 if the resulting mask was non-zero, and 0 otherwise.
      * aka, "Is there even a partial match?", even if it wasn't a full match.
  * `i`: store the generated index in dst.
      * The index of the match. This can be the first match or the last match, depending on if you pick least or most significant.
  * `m`: store the generated mask in dst.
      * Gives the mask of the matches themselves. This can be in bits (one bit par char) or in char units (`u8`/`u16` per char, depending on char size).
  * `o`: returns bit 0 of the resulting bit mask
      * (fairly useless)
  * `s`: returns 1 if any character in a was null, and 0 otherwise
      * for explicit length strings: this tells you if the string length is less than the lane maximum (useless)
      * For implied length strings this lets you do strlen.
  * `z`: returns 1 if any character in b was null, and 0 otherwise
      * for explicit length strings: this tells you if the string length is less than the lane maximum (useless)
      * For implied length strings this lets you do strlen.

## Example Tasks And How To Do Them

???

// finfine
