GNU Linux-libre 4.14.251-gnu1
[releases.git] / arch / sparc / lib / strlen.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* strlen.S: Sparc optimized strlen code
3  * Hand optimized from GNU libc's strlen
4  * Copyright (C) 1991,1996 Free Software Foundation
5  * Copyright (C) 1996,2008 David S. Miller (davem@davemloft.net)
6  * Copyright (C) 1996, 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
7  */
8
9 #include <linux/linkage.h>
10 #include <asm/asm.h>
11 #include <asm/export.h>
12
13 #define LO_MAGIC 0x01010101
14 #define HI_MAGIC 0x80808080
15
16         .text
17 ENTRY(strlen)
18         mov     %o0, %o1
19         andcc   %o0, 3, %g0
20         BRANCH32(be, pt, 9f)
21          sethi  %hi(HI_MAGIC), %o4
22         ldub    [%o0], %o5
23         BRANCH_REG_ZERO(pn, %o5, 11f)
24          add    %o0, 1, %o0
25         andcc   %o0, 3, %g0
26         BRANCH32(be, pn, 4f)
27          or     %o4, %lo(HI_MAGIC), %o3
28         ldub    [%o0], %o5
29         BRANCH_REG_ZERO(pn, %o5, 12f)
30          add    %o0, 1, %o0
31         andcc   %o0, 3, %g0
32         BRANCH32(be, pt, 5f)
33          sethi  %hi(LO_MAGIC), %o4
34         ldub    [%o0], %o5
35         BRANCH_REG_ZERO(pn, %o5, 13f)
36          add    %o0, 1, %o0
37         BRANCH32(ba, pt, 8f)
38          or     %o4, %lo(LO_MAGIC), %o2
39 9:
40         or      %o4, %lo(HI_MAGIC), %o3
41 4:
42         sethi   %hi(LO_MAGIC), %o4
43 5:
44         or      %o4, %lo(LO_MAGIC), %o2
45 8:
46         ld      [%o0], %o5
47 2:
48         sub     %o5, %o2, %o4
49         andcc   %o4, %o3, %g0
50         BRANCH32(be, pt, 8b)
51          add    %o0, 4, %o0
52
53         /* Check every byte. */
54         srl     %o5, 24, %g7
55         andcc   %g7, 0xff, %g0
56         BRANCH32(be, pn, 1f)
57          add    %o0, -4, %o4
58         srl     %o5, 16, %g7
59         andcc   %g7, 0xff, %g0
60         BRANCH32(be, pn, 1f)
61          add    %o4, 1, %o4
62         srl     %o5, 8, %g7
63         andcc   %g7, 0xff, %g0
64         BRANCH32(be, pn, 1f)
65          add    %o4, 1, %o4
66         andcc   %o5, 0xff, %g0
67         BRANCH32_ANNUL(bne, pt, 2b)
68          ld     [%o0], %o5
69         add     %o4, 1, %o4
70 1:
71         retl
72          sub    %o4, %o1, %o0
73 11:
74         retl
75          mov    0, %o0
76 12:
77         retl
78          mov    1, %o0
79 13:
80         retl
81          mov    2, %o0
82 ENDPROC(strlen)
83 EXPORT_SYMBOL(strlen)