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 }