...
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
19size_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}
View as plain text