1 #ifndef _STRINGS_H
2 #define _STRINGS_H
3 
4 /** @file
5  *
6  * String functions
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <string.h>
13 #include <bits/strings.h>
14 
15 /**
16  * Find first (i.e. least significant) set bit
17  *
18  * @v x			Value
19  * @ret lsb		Least significant bit set in value (LSB=1), or zero
20  */
21 static inline __attribute__ (( always_inline )) int
__constant_ffsll(unsigned long long x)22 __constant_ffsll ( unsigned long long x ) {
23 	int r = 0;
24 
25 	if ( ! ( x & 0x00000000ffffffffULL ) ) {
26 		x >>= 32;
27 		r += 32;
28 	}
29 	if ( ! ( x & 0x0000ffffUL ) ) {
30 		x >>= 16;
31 		r += 16;
32 	}
33 	if ( ! ( x & 0x00ff ) ) {
34 		x >>= 8;
35 		r += 8;
36 	}
37 	if ( ! ( x & 0x0f ) ) {
38 		x >>= 4;
39 		r += 4;
40 	}
41 	if ( ! ( x & 0x3 ) ) {
42 		x >>= 2;
43 		r += 2;
44 	}
45 	if ( ! ( x & 0x1 ) ) {
46 		x >>= 1;
47 		r += 1;
48 	}
49 	return ( x ? ( r + 1 ) : 0 );
50 }
51 
52 /**
53  * Find first (i.e. least significant) set bit
54  *
55  * @v x			Value
56  * @ret lsb		Least significant bit set in value (LSB=1), or zero
57  */
58 static inline __attribute__ (( always_inline )) int
__constant_ffsl(unsigned long x)59 __constant_ffsl ( unsigned long x ) {
60 	return __constant_ffsll ( x );
61 }
62 
63 /**
64  * Find last (i.e. most significant) set bit
65  *
66  * @v x			Value
67  * @ret msb		Most significant bit set in value (LSB=1), or zero
68  */
69 static inline __attribute__ (( always_inline )) int
__constant_flsll(unsigned long long x)70 __constant_flsll ( unsigned long long x ) {
71 	int r = 0;
72 
73 	if ( x & 0xffffffff00000000ULL ) {
74 		x >>= 32;
75 		r += 32;
76 	}
77 	if ( x & 0xffff0000UL ) {
78 		x >>= 16;
79 		r += 16;
80 	}
81 	if ( x & 0xff00 ) {
82 		x >>= 8;
83 		r += 8;
84 	}
85 	if ( x & 0xf0 ) {
86 		x >>= 4;
87 		r += 4;
88 	}
89 	if ( x & 0xc ) {
90 		x >>= 2;
91 		r += 2;
92 	}
93 	if ( x & 0x2 ) {
94 		x >>= 1;
95 		r += 1;
96 	}
97 	return ( x ? ( r + 1 ) : 0 );
98 }
99 
100 /**
101  * Find last (i.e. most significant) set bit
102  *
103  * @v x			Value
104  * @ret msb		Most significant bit set in value (LSB=1), or zero
105  */
106 static inline __attribute__ (( always_inline )) int
__constant_flsl(unsigned long x)107 __constant_flsl ( unsigned long x ) {
108 	return __constant_flsll ( x );
109 }
110 
111 int __ffsll ( long long x );
112 int __ffsl ( long x );
113 int __flsll ( long long x );
114 int __flsl ( long x );
115 
116 /**
117  * Find first (i.e. least significant) set bit
118  *
119  * @v x			Value
120  * @ret lsb		Least significant bit set in value (LSB=1), or zero
121  */
122 #define ffsll( x ) \
123 	( __builtin_constant_p ( x ) ? __constant_ffsll ( x ) : __ffsll ( x ) )
124 
125 /**
126  * Find first (i.e. least significant) set bit
127  *
128  * @v x			Value
129  * @ret lsb		Least significant bit set in value (LSB=1), or zero
130  */
131 #define ffsl( x ) \
132 	( __builtin_constant_p ( x ) ? __constant_ffsl ( x ) : __ffsl ( x ) )
133 
134 /**
135  * Find first (i.e. least significant) set bit
136  *
137  * @v x			Value
138  * @ret lsb		Least significant bit set in value (LSB=1), or zero
139  */
140 #define ffs( x ) ffsl ( x )
141 
142 /**
143  * Find last (i.e. most significant) set bit
144  *
145  * @v x			Value
146  * @ret msb		Most significant bit set in value (LSB=1), or zero
147  */
148 #define flsll( x ) \
149 	( __builtin_constant_p ( x ) ? __constant_flsll ( x ) : __flsll ( x ) )
150 
151 /**
152  * Find last (i.e. most significant) set bit
153  *
154  * @v x			Value
155  * @ret msb		Most significant bit set in value (LSB=1), or zero
156  */
157 #define flsl( x ) \
158 	( __builtin_constant_p ( x ) ? __constant_flsl ( x ) : __flsl ( x ) )
159 
160 /**
161  * Find last (i.e. most significant) set bit
162  *
163  * @v x			Value
164  * @ret msb		Most significant bit set in value (LSB=1), or zero
165  */
166 #define fls( x ) flsl ( x )
167 
168 /**
169  * Copy memory
170  *
171  * @v src		Source
172  * @v dest		Destination
173  * @v len		Length
174  */
175 static inline __attribute__ (( always_inline )) void
bcopy(const void * src,void * dest,size_t len)176 bcopy ( const void *src, void *dest, size_t len ) {
177 	memmove ( dest, src, len );
178 }
179 
180 /**
181  * Zero memory
182  *
183  * @v dest		Destination
184  * @v len		Length
185  */
186 static inline __attribute__ (( always_inline )) void
bzero(void * dest,size_t len)187 bzero ( void *dest, size_t len ) {
188 	memset ( dest, 0, len );
189 }
190 
191 int __pure strcasecmp ( const char *first, const char *second ) __nonnull;
192 
193 #endif /* _STRINGS_H */
194