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