1 | /* Zero byte detection; indexes. Generic C version. |
2 | Copyright (C) 2023-2024 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ |
18 | |
19 | #ifndef _STRING_FZC_H |
20 | #define _STRING_FZC_H 1 |
21 | |
22 | #include <endian.h> |
23 | #include <string-fza.h> |
24 | #include <string-fzi.h> |
25 | |
26 | |
27 | /* Given a word X that is known to contain a zero byte, return the index of |
28 | the first such within the word in memory order. */ |
29 | static __always_inline unsigned int |
30 | index_first_zero (op_t x) |
31 | { |
32 | if (__BYTE_ORDER == __LITTLE_ENDIAN) |
33 | x = find_zero_low (x); |
34 | else |
35 | x = find_zero_all (x); |
36 | return index_first (c: x); |
37 | } |
38 | |
39 | /* Similarly, but perform the search for byte equality between X1 and X2. */ |
40 | static __always_inline unsigned int |
41 | index_first_eq (op_t x1, op_t x2) |
42 | { |
43 | if (__BYTE_ORDER == __LITTLE_ENDIAN) |
44 | x1 = find_eq_low (x1, x2); |
45 | else |
46 | x1 = find_eq_all (x1, x2); |
47 | return index_first (c: x1); |
48 | } |
49 | |
50 | /* Similarly, but perform the search for zero within X1 or equality between |
51 | X1 and X2. */ |
52 | static __always_inline unsigned int |
53 | index_first_zero_eq (op_t x1, op_t x2) |
54 | { |
55 | if (__BYTE_ORDER == __LITTLE_ENDIAN) |
56 | x1 = find_zero_eq_low (x1, x2); |
57 | else |
58 | x1 = find_zero_eq_all (x1, x2); |
59 | return index_first (c: x1); |
60 | } |
61 | |
62 | /* Similarly, but perform the search for zero within X1 or inequality between |
63 | X1 and X2. */ |
64 | static __always_inline unsigned int |
65 | index_first_zero_ne (op_t x1, op_t x2) |
66 | { |
67 | return index_first (c: find_zero_ne_all (x1, x2)); |
68 | } |
69 | |
70 | /* Similarly, but search for the last zero within X. */ |
71 | static __always_inline unsigned int |
72 | index_last_zero (op_t x) |
73 | { |
74 | if (__BYTE_ORDER == __LITTLE_ENDIAN) |
75 | x = find_zero_all (x); |
76 | else |
77 | x = find_zero_low (x); |
78 | return index_last (c: x); |
79 | } |
80 | |
81 | static __always_inline unsigned int |
82 | index_last_eq (op_t x1, op_t x2) |
83 | { |
84 | return index_last_zero (x: x1 ^ x2); |
85 | } |
86 | |
87 | #endif /* STRING_FZC_H */ |
88 | |