]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/string/xtensa/strlen.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / string / xtensa / strlen.S
1 /* Optimized strlen for Xtensa.
2    Copyright (C) 2001, 2007 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 #include <sysdep.h>
20 #include <bits/xtensa-config.h>
21
22 #ifdef __XTENSA_EB__
23 #define MASK0 0xff000000
24 #define MASK1 0x00ff0000
25 #define MASK2 0x0000ff00
26 #define MASK3 0x000000ff
27 #else
28 #define MASK0 0x000000ff
29 #define MASK1 0x0000ff00
30 #define MASK2 0x00ff0000
31 #define MASK3 0xff000000
32 #endif
33
34         .text
35 ENTRY (strlen)
36         /* a2 = s */
37
38         addi    a3, a2, -4      /* because we overincrement at the end */
39         movi    a4, MASK0
40         movi    a5, MASK1
41         movi    a6, MASK2
42         movi    a7, MASK3
43         bbsi.l  a2, 0, .L1mod2
44         bbsi.l  a2, 1, .L2mod4
45         j       .Laligned
46
47 .L1mod2: /* address is odd */
48         l8ui    a8, a3, 4       /* get byte 0 */
49         addi    a3, a3, 1       /* advance string pointer */
50         beqz    a8, .Lz3        /* if byte 0 is zero */
51         bbci.l  a3, 1, .Laligned /* if string pointer is now word-aligned */
52
53 .L2mod4: /* address is 2 mod 4 */
54         addi    a3, a3, 2       /* advance ptr for aligned access */
55         l32i    a8, a3, 0       /* get word with first two bytes of string */
56         bnone   a8, a6, .Lz2    /* if byte 2 (of word, not string) is zero */
57         bany    a8, a7, .Laligned /* if byte 3 (of word, not string) is nonzero */
58
59         /* Byte 3 is zero.  */
60         addi    a3, a3, 3       /* point to zero byte */
61         sub     a2, a3, a2      /* subtract to get length */
62         retw
63
64
65 /* String is word-aligned.  */
66
67         .align  4
68         /* (2 mod 4) alignment for loop instruction */
69 .Laligned:
70 #if XCHAL_HAVE_LOOPS
71         _movi.n a8, 0           /* set up for the maximum loop count */
72         loop    a8, .Lz3        /* loop forever (almost anyway) */
73 #endif
74 1:      l32i    a8, a3, 4       /* get next word of string */
75         addi    a3, a3, 4       /* advance string pointer */
76         bnone   a8, a4, .Lz0    /* if byte 0 is zero */
77         bnone   a8, a5, .Lz1    /* if byte 1 is zero */
78         bnone   a8, a6, .Lz2    /* if byte 2 is zero */
79 #if XCHAL_HAVE_LOOPS
80         bnone   a8, a7, .Lz3    /* if byte 3 is zero */
81 #else
82         bany    a8, a7, 1b      /* repeat if byte 3 is non-zero */
83 #endif
84
85 .Lz3:   /* Byte 3 is zero.  */
86         addi    a3, a3, 3       /* point to zero byte */
87         /* Fall through....  */
88
89 .Lz0:   /* Byte 0 is zero.  */
90         sub     a2, a3, a2      /* subtract to get length */
91         retw
92
93 .Lz1:   /* Byte 1 is zero.  */
94         addi    a3, a3, 1       /* point to zero byte */
95         sub     a2, a3, a2      /* subtract to get length */
96         retw
97
98 .Lz2:   /* Byte 2 is zero.  */
99         addi    a3, a3, 2       /* point to zero byte */
100         sub     a2, a3, a2      /* subtract to get length */
101         retw
102
103 libc_hidden_def (strlen)