github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/native/fastbytes.c (about)

     1  /*
     2   * Copyright 2021 ByteDance Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  #include "native.h"
    18  
    19  size_t lspace(const char *sp, size_t nb, size_t p) {
    20      const char * ss = sp;
    21  
    22      /* seek to `p` */
    23      sp += p;
    24      nb -= p;
    25  
    26      /* likely to run into non-spaces within a few characters, try scalar code first */
    27  #if USE_AVX2
    28      __m256i space_tab = _mm256_setr_epi8(
    29          '\x20', 0, 0, 0, 0, 0, 0, 0,
    30           0, '\x09', '\x0A', 0, 0, '\x0D', 0, 0,
    31          '\x20', 0, 0, 0, 0, 0, 0, 0,
    32           0, '\x09', '\x0A', 0, 0, '\x0D', 0, 0
    33      );
    34  
    35      /* 32-byte loop */
    36      while (likely(nb >= 32)) {
    37          __m256i input = _mm256_loadu_si256((__m256i*)sp);
    38          __m256i shuffle = _mm256_shuffle_epi8(space_tab, input);
    39          __m256i result = _mm256_cmpeq_epi8(input, shuffle);
    40          int32_t mask = _mm256_movemask_epi8(result);
    41          if (mask != -1) {
    42              return sp - ss + __builtin_ctzll(~(uint64_t)mask);
    43          }
    44          sp += 32;
    45          nb -= 32;
    46      }
    47  #endif
    48  
    49      /* remaining bytes, do with scalar code */
    50      while (nb-- > 0) {
    51          switch (*sp++) {
    52              case ' '  : break;
    53              case '\r' : break;
    54              case '\n' : break;
    55              case '\t' : break;
    56              default   : return sp - ss - 1;
    57          }
    58      }
    59  
    60      /* all the characters are spaces */
    61      return sp - ss;
    62  }