Search code examples
csseintrinsics

Finding Next Ascii Space With _mm_cmpeq_epi8 Returning 0


I have this string being passed into my parse route method.

  route_start = 4;
  parse_route_simd("GET /0000_0000_/ HTTP/1.1\r\n", 27);
  assert(route_end == 15);
const char spaces[17] __attribute__((aligned(16))) = "                \0";

 void parse_route_simd(const char *buffer, const int buffer_len) {
  int index_simd;
  int curr_index = route_start;
  register __m128i xmm0, xmm1, xmm2;
  register unsigned int eax;
  register unsigned char ebx;
  while (buffer_len - curr_index >= 16) {
    debug_print("route_start %d\nindex_simd %d\nbuff %s\nspaces :%s:\n",
                route_start, index_simd, buffer + curr_index, spaces);
    xmm0 = _mm_loadu_si128((const __m128i *)buffer + curr_index);
    xmm1 = _mm_loadu_si128((const __m128i *)spaces);
    xmm2 = _mm_cmpeq_epi8(xmm0, xmm1);
    eax = _mm_movemask_epi8(xmm2);
    debug_print("eax %d\n", eax);
    index_simd = __builtin_ffsll(eax);

I am losing my mind, because I can't figure out why eax in this code is returning 0;


Solution

  • (const __m128i *)buffer + curr_index is a problem.
    You need (const __m128i *)(buffer + curr_index) to do char* address math, then cast to __m128i*.

    casts have higher operator precedence than +.

    Another common technique to avoid this mistake is (__m128i*) &buffer[curr_index]

    A debugger should show that with curr_index = 1, you're loading from 16 bytes into the array, going forward by one __m128i, because that's the pointer type involved in the addition.