github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/native/lspace.h (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  #pragma once
    18  
    19  #include "native.h"
    20  
    21  static always_inline size_t lspace_1(const char *sp, size_t nb, size_t p) {
    22      const char * ss = sp;
    23  
    24      /* seek to `p` */
    25      sp += p;
    26      nb -= p;
    27  
    28      /* likely to run into non-spaces within a few characters, try scalar code first */
    29  #if USE_AVX2
    30      __m256i space_tab = _mm256_setr_epi8(
    31          '\x20', 0, 0, 0, 0, 0, 0, 0,
    32           0, '\x09', '\x0A', 0, 0, '\x0D', 0, 0,
    33          '\x20', 0, 0, 0, 0, 0, 0, 0,
    34           0, '\x09', '\x0A', 0, 0, '\x0D', 0, 0
    35      );
    36  
    37      /* 32-byte loop */
    38      while (likely(nb >= 32)) {
    39          __m256i input = _mm256_loadu_si256((__m256i*)sp);
    40          __m256i shuffle = _mm256_shuffle_epi8(space_tab, input);
    41          __m256i result = _mm256_cmpeq_epi8(input, shuffle);
    42          int32_t mask = _mm256_movemask_epi8(result);
    43          if (mask != -1) {
    44              return sp - ss + __builtin_ctzll(~(uint64_t)mask);
    45          }
    46          sp += 32;
    47          nb -= 32;
    48      }
    49  #endif
    50  
    51      /* remaining bytes, do with scalar code */
    52      while (nb-- > 0) {
    53          switch (*sp++) {
    54              case ' '  : break;
    55              case '\r' : break;
    56              case '\n' : break;
    57              case '\t' : break;
    58              default   : return sp - ss - 1;
    59          }
    60      }
    61  
    62      /* all the characters are spaces */
    63      return sp - ss;
    64  }