Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
s390
lib
string.c
Go to the documentation of this file.
1
/*
2
* Optimized string functions
3
*
4
* S390 version
5
* Copyright IBM Corp. 2004
6
* Author(s): Martin Schwidefsky (
[email protected]
)
7
*/
8
9
#define IN_ARCH_STRING_C 1
10
11
#include <linux/types.h>
12
#include <linux/module.h>
13
14
/*
15
* Helper functions to find the end of a string
16
*/
17
static
inline
char
*__strend(
const
char
*
s
)
18
{
19
register
unsigned
long
r0
asm
(
"0"
) = 0;
20
21
asm
volatile
(
"0: srst %0,%1\n"
22
" jo 0b"
23
:
"+d"
(
r0
),
"+a"
(s) : :
"cc"
);
24
return
(
char
*)
r0
;
25
}
26
27
static
inline
char
*__strnend(
const
char
*
s
,
size_t
n
)
28
{
29
register
unsigned
long
r0
asm
(
"0"
) = 0;
30
const
char
*
p
= s +
n
;
31
32
asm
volatile
(
"0: srst %0,%1\n"
33
" jo 0b"
34
:
"+d"
(
p
),
"+a"
(s) :
"d"
(
r0
) :
"cc"
);
35
return
(
char
*)
p
;
36
}
37
44
size_t
strlen
(
const
char
*s)
45
{
46
return
__strend(s) -
s
;
47
}
48
EXPORT_SYMBOL
(
strlen
);
49
57
size_t
strnlen
(
const
char
* s,
size_t
n)
58
{
59
return
__strnend(s, n) -
s
;
60
}
61
EXPORT_SYMBOL
(strnlen);
62
70
char
*
strcpy
(
char
*
dest
,
const
char
*
src
)
71
{
72
register
int
r0
asm
(
"0"
) = 0;
73
char
*
ret
=
dest
;
74
75
asm
volatile
(
"0: mvst %0,%1\n"
76
" jo 0b"
77
:
"+&a"
(
dest
),
"+&a"
(src) :
"d"
(
r0
)
78
:
"cc"
,
"memory"
);
79
return
ret
;
80
}
81
EXPORT_SYMBOL
(
strcpy
);
82
94
size_t
strlcpy
(
char
*
dest
,
const
char
*
src
,
size_t
size
)
95
{
96
size_t
ret
= __strend(src) -
src
;
97
98
if
(size) {
99
size_t
len
= (ret >=
size
) ? size-1 : ret;
100
dest[len] =
'\0'
;
101
memcpy
(dest, src, len);
102
}
103
return
ret
;
104
}
105
EXPORT_SYMBOL
(
strlcpy
);
106
116
char
*
strncpy
(
char
*
dest
,
const
char
*
src
,
size_t
n)
117
{
118
size_t
len
= __strnend(src, n) -
src
;
119
memset
(dest + len, 0, n - len);
120
memcpy
(dest, src, len);
121
return
dest
;
122
}
123
EXPORT_SYMBOL
(strncpy);
124
132
char
*
strcat
(
char
*
dest
,
const
char
*
src
)
133
{
134
register
int
r0
asm
(
"0"
) = 0;
135
unsigned
long
dummy
;
136
char
*
ret
=
dest
;
137
138
asm
volatile
(
"0: srst %0,%1\n"
139
" jo 0b\n"
140
"1: mvst %0,%2\n"
141
" jo 1b"
142
:
"=&a"
(
dummy
),
"+a"
(dest),
"+a"
(
src
)
143
:
"d"
(
r0
),
"0"
(0
UL
) :
"cc"
,
"memory"
);
144
return
ret
;
145
}
146
EXPORT_SYMBOL
(
strcat
);
147
154
size_t
strlcat
(
char
*
dest
,
const
char
*
src
,
size_t
n)
155
{
156
size_t
dsize = __strend(dest) -
dest
;
157
size_t
len
= __strend(src) -
src
;
158
size_t
res
= dsize + len;
159
160
if
(dsize < n) {
161
dest += dsize;
162
n -= dsize;
163
if
(len >= n)
164
len = n - 1;
165
dest[len] =
'\0'
;
166
memcpy
(dest, src, len);
167
}
168
return
res
;
169
}
170
EXPORT_SYMBOL
(
strlcat
);
171
183
char
*
strncat
(
char
*
dest
,
const
char
*
src
,
size_t
n)
184
{
185
size_t
len
= __strnend(src, n) -
src
;
186
char
*p = __strend(dest);
187
188
p[len] =
'\0'
;
189
memcpy
(p, src, len);
190
return
dest
;
191
}
192
EXPORT_SYMBOL
(
strncat
);
193
203
int
strcmp
(
const
char
*
cs
,
const
char
*
ct
)
204
{
205
register
int
r0
asm
(
"0"
) = 0;
206
int
ret
= 0;
207
208
asm
volatile
(
"0: clst %2,%3\n"
209
" jo 0b\n"
210
" je 1f\n"
211
" ic %0,0(%2)\n"
212
" ic %1,0(%3)\n"
213
" sr %0,%1\n"
214
"1:"
215
:
"+d"
(
ret
),
"+d"
(
r0
),
"+a"
(
cs
),
"+a"
(ct)
216
: :
"cc"
);
217
return
ret
;
218
}
219
EXPORT_SYMBOL
(
strcmp
);
220
226
char
*
strrchr
(
const
char
* s,
int
c
)
227
{
228
size_t
len
= __strend(s) -
s
;
229
230
if
(len)
231
do
{
232
if
(s[len] == (
char
) c)
233
return
(
char
*) s + len;
234
}
while
(--len > 0);
235
return
NULL
;
236
}
237
EXPORT_SYMBOL
(
strrchr
);
238
244
char
*
strstr
(
const
char
*
s1
,
const
char
*
s2
)
245
{
246
int
l1
,
l2
;
247
248
l2 = __strend(s2) -
s2
;
249
if
(!l2)
250
return
(
char
*)
s1
;
251
l1 = __strend(s1) -
s1
;
252
while
(l1-- >= l2) {
253
register
unsigned
long
r2
asm
(
"2"
) = (
unsigned
long
)
s1
;
254
register
unsigned
long
r3
asm
(
"3"
) = (
unsigned
long
)
l2
;
255
register
unsigned
long
r4
asm
(
"4"
) = (
unsigned
long
)
s2
;
256
register
unsigned
long
r5
asm
(
"5"
) = (
unsigned
long
)
l2
;
257
int
cc
;
258
259
asm
volatile
(
"0: clcle %1,%3,0\n"
260
" jo 0b\n"
261
" ipm %0\n"
262
" srl %0,28"
263
:
"=&d"
(
cc
),
"+a"
(
r2
),
"+a"
(
r3
),
264
"+a"
(
r4
),
"+a"
(
r5
) : :
"cc"
);
265
if
(!cc)
266
return
(
char
*)
s1
;
267
s1++;
268
}
269
return
NULL
;
270
}
271
EXPORT_SYMBOL
(
strstr
);
272
282
void
*
memchr
(
const
void
*s,
int
c
,
size_t
n)
283
{
284
register
int
r0
asm
(
"0"
) = (
char
)
c
;
285
const
void
*
ret
= s +
n
;
286
287
asm
volatile
(
"0: srst %0,%1\n"
288
" jo 0b\n"
289
" jl 1f\n"
290
" la %0,0\n"
291
"1:"
292
:
"+a"
(
ret
),
"+&a"
(s) :
"d"
(
r0
) :
"cc"
);
293
return
(
void
*)
ret
;
294
}
295
EXPORT_SYMBOL
(
memchr
);
296
303
int
memcmp
(
const
void
*
cs
,
const
void
*
ct
,
size_t
n)
304
{
305
register
unsigned
long
r2
asm
(
"2"
) = (
unsigned
long
)
cs
;
306
register
unsigned
long
r3
asm
(
"3"
) = (
unsigned
long
)
n
;
307
register
unsigned
long
r4
asm
(
"4"
) = (
unsigned
long
)
ct
;
308
register
unsigned
long
r5
asm
(
"5"
) = (
unsigned
long
)
n
;
309
int
ret
;
310
311
asm
volatile
(
"0: clcle %1,%3,0\n"
312
" jo 0b\n"
313
" ipm %0\n"
314
" srl %0,28"
315
:
"=&d"
(
ret
),
"+a"
(
r2
),
"+a"
(
r3
),
"+a"
(
r4
),
"+a"
(
r5
)
316
: :
"cc"
);
317
if
(ret)
318
ret = *(
char
*)
r2
- *(
char
*)
r4
;
319
return
ret
;
320
}
321
EXPORT_SYMBOL
(
memcmp
);
322
332
void
*
memscan
(
void
*s,
int
c
,
size_t
n)
333
{
334
register
int
r0
asm
(
"0"
) = (
char
)
c
;
335
const
void
*
ret
= s +
n
;
336
337
asm
volatile
(
"0: srst %0,%1\n"
338
" jo 0b\n"
339
:
"+a"
(
ret
),
"+&a"
(s) :
"d"
(
r0
) :
"cc"
);
340
return
(
void
*)
ret
;
341
}
342
EXPORT_SYMBOL
(memscan);
Generated on Thu Jan 10 2013 12:54:52 for Linux Kernel by
1.8.2