xref: /freebsd/contrib/cortex-strings/src/thumb-2/strlen.S (revision 8c4282b370bd66908b45b6a223226a9fc2b69d57)
1*09a53ad8SAndrew Turner/* Copyright (c) 2010-2011,2013 Linaro Limited
2*09a53ad8SAndrew Turner   All rights reserved.
3*09a53ad8SAndrew Turner
4*09a53ad8SAndrew Turner   Redistribution and use in source and binary forms, with or without
5*09a53ad8SAndrew Turner   modification, are permitted provided that the following conditions
6*09a53ad8SAndrew Turner   are met:
7*09a53ad8SAndrew Turner
8*09a53ad8SAndrew Turner      * Redistributions of source code must retain the above copyright
9*09a53ad8SAndrew Turner      notice, this list of conditions and the following disclaimer.
10*09a53ad8SAndrew Turner
11*09a53ad8SAndrew Turner      * Redistributions in binary form must reproduce the above copyright
12*09a53ad8SAndrew Turner      notice, this list of conditions and the following disclaimer in the
13*09a53ad8SAndrew Turner      documentation and/or other materials provided with the distribution.
14*09a53ad8SAndrew Turner
15*09a53ad8SAndrew Turner      * Neither the name of Linaro Limited nor the names of its
16*09a53ad8SAndrew Turner      contributors may be used to endorse or promote products derived
17*09a53ad8SAndrew Turner      from this software without specific prior written permission.
18*09a53ad8SAndrew Turner
19*09a53ad8SAndrew Turner   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*09a53ad8SAndrew Turner   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*09a53ad8SAndrew Turner   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22*09a53ad8SAndrew Turner   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23*09a53ad8SAndrew Turner   HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*09a53ad8SAndrew Turner   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25*09a53ad8SAndrew Turner   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26*09a53ad8SAndrew Turner   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27*09a53ad8SAndrew Turner   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28*09a53ad8SAndrew Turner   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29*09a53ad8SAndrew Turner   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*09a53ad8SAndrew Turner */
31*09a53ad8SAndrew Turner
32*09a53ad8SAndrew Turner/*
33*09a53ad8SAndrew Turner   Assumes:
34*09a53ad8SAndrew Turner   ARMv6T2, AArch32
35*09a53ad8SAndrew Turner
36*09a53ad8SAndrew Turner */
37*09a53ad8SAndrew Turner
38*09a53ad8SAndrew Turner	.macro def_fn f p2align=0
39*09a53ad8SAndrew Turner	.text
40*09a53ad8SAndrew Turner	.p2align \p2align
41*09a53ad8SAndrew Turner	.global \f
42*09a53ad8SAndrew Turner	.type \f, %function
43*09a53ad8SAndrew Turner\f:
44*09a53ad8SAndrew Turner	.endm
45*09a53ad8SAndrew Turner
46*09a53ad8SAndrew Turner#ifdef __ARMEB__
47*09a53ad8SAndrew Turner#define S2LO		lsl
48*09a53ad8SAndrew Turner#define S2HI		lsr
49*09a53ad8SAndrew Turner#else
50*09a53ad8SAndrew Turner#define S2LO		lsr
51*09a53ad8SAndrew Turner#define S2HI		lsl
52*09a53ad8SAndrew Turner#endif
53*09a53ad8SAndrew Turner
54*09a53ad8SAndrew Turner	/* This code requires Thumb.  */
55*09a53ad8SAndrew Turner	.thumb
56*09a53ad8SAndrew Turner	.syntax unified
57*09a53ad8SAndrew Turner
58*09a53ad8SAndrew Turner/* Parameters and result.  */
59*09a53ad8SAndrew Turner#define srcin		r0
60*09a53ad8SAndrew Turner#define result		r0
61*09a53ad8SAndrew Turner
62*09a53ad8SAndrew Turner/* Internal variables.  */
63*09a53ad8SAndrew Turner#define src		r1
64*09a53ad8SAndrew Turner#define data1a		r2
65*09a53ad8SAndrew Turner#define data1b		r3
66*09a53ad8SAndrew Turner#define const_m1	r12
67*09a53ad8SAndrew Turner#define const_0		r4
68*09a53ad8SAndrew Turner#define tmp1		r4		/* Overlaps const_0  */
69*09a53ad8SAndrew Turner#define tmp2		r5
70*09a53ad8SAndrew Turner
71*09a53ad8SAndrew Turnerdef_fn	strlen p2align=6
72*09a53ad8SAndrew Turner	pld	[srcin, #0]
73*09a53ad8SAndrew Turner	strd	r4, r5, [sp, #-8]!
74*09a53ad8SAndrew Turner	bic	src, srcin, #7
75*09a53ad8SAndrew Turner	mvn	const_m1, #0
76*09a53ad8SAndrew Turner	ands	tmp1, srcin, #7		/* (8 - bytes) to alignment.  */
77*09a53ad8SAndrew Turner	pld	[src, #32]
78*09a53ad8SAndrew Turner	bne.w	.Lmisaligned8
79*09a53ad8SAndrew Turner	mov	const_0, #0
80*09a53ad8SAndrew Turner	mov	result, #-8
81*09a53ad8SAndrew Turner.Lloop_aligned:
82*09a53ad8SAndrew Turner	/* Bytes 0-7.  */
83*09a53ad8SAndrew Turner	ldrd	data1a, data1b, [src]
84*09a53ad8SAndrew Turner	pld	[src, #64]
85*09a53ad8SAndrew Turner	add	result, result, #8
86*09a53ad8SAndrew Turner.Lstart_realigned:
87*09a53ad8SAndrew Turner	uadd8	data1a, data1a, const_m1	/* Saturating GE<0:3> set.  */
88*09a53ad8SAndrew Turner	sel	data1a, const_0, const_m1	/* Select based on GE<0:3>.  */
89*09a53ad8SAndrew Turner	uadd8	data1b, data1b, const_m1
90*09a53ad8SAndrew Turner	sel	data1b, data1a, const_m1	/* Only used if d1a == 0.  */
91*09a53ad8SAndrew Turner	cbnz	data1b, .Lnull_found
92*09a53ad8SAndrew Turner
93*09a53ad8SAndrew Turner	/* Bytes 8-15.  */
94*09a53ad8SAndrew Turner	ldrd	data1a, data1b, [src, #8]
95*09a53ad8SAndrew Turner	uadd8	data1a, data1a, const_m1	/* Saturating GE<0:3> set.  */
96*09a53ad8SAndrew Turner	add	result, result, #8
97*09a53ad8SAndrew Turner	sel	data1a, const_0, const_m1	/* Select based on GE<0:3>.  */
98*09a53ad8SAndrew Turner	uadd8	data1b, data1b, const_m1
99*09a53ad8SAndrew Turner	sel	data1b, data1a, const_m1	/* Only used if d1a == 0.  */
100*09a53ad8SAndrew Turner	cbnz	data1b, .Lnull_found
101*09a53ad8SAndrew Turner
102*09a53ad8SAndrew Turner	/* Bytes 16-23.  */
103*09a53ad8SAndrew Turner	ldrd	data1a, data1b, [src, #16]
104*09a53ad8SAndrew Turner	uadd8	data1a, data1a, const_m1	/* Saturating GE<0:3> set.  */
105*09a53ad8SAndrew Turner	add	result, result, #8
106*09a53ad8SAndrew Turner	sel	data1a, const_0, const_m1	/* Select based on GE<0:3>.  */
107*09a53ad8SAndrew Turner	uadd8	data1b, data1b, const_m1
108*09a53ad8SAndrew Turner	sel	data1b, data1a, const_m1	/* Only used if d1a == 0.  */
109*09a53ad8SAndrew Turner	cbnz	data1b, .Lnull_found
110*09a53ad8SAndrew Turner
111*09a53ad8SAndrew Turner	/* Bytes 24-31.  */
112*09a53ad8SAndrew Turner	ldrd	data1a, data1b, [src, #24]
113*09a53ad8SAndrew Turner	add	src, src, #32
114*09a53ad8SAndrew Turner	uadd8	data1a, data1a, const_m1	/* Saturating GE<0:3> set.  */
115*09a53ad8SAndrew Turner	add	result, result, #8
116*09a53ad8SAndrew Turner	sel	data1a, const_0, const_m1	/* Select based on GE<0:3>.  */
117*09a53ad8SAndrew Turner	uadd8	data1b, data1b, const_m1
118*09a53ad8SAndrew Turner	sel	data1b, data1a, const_m1	/* Only used if d1a == 0.  */
119*09a53ad8SAndrew Turner	cmp	data1b, #0
120*09a53ad8SAndrew Turner	beq	.Lloop_aligned
121*09a53ad8SAndrew Turner
122*09a53ad8SAndrew Turner.Lnull_found:
123*09a53ad8SAndrew Turner	cmp	data1a, #0
124*09a53ad8SAndrew Turner	itt	eq
125*09a53ad8SAndrew Turner	addeq	result, result, #4
126*09a53ad8SAndrew Turner	moveq	data1a, data1b
127*09a53ad8SAndrew Turner#ifndef __ARMEB__
128*09a53ad8SAndrew Turner	rev	data1a, data1a
129*09a53ad8SAndrew Turner#endif
130*09a53ad8SAndrew Turner	clz	data1a, data1a
131*09a53ad8SAndrew Turner	ldrd	r4, r5, [sp], #8
132*09a53ad8SAndrew Turner	add	result, result, data1a, lsr #3	/* Bits -> Bytes.  */
133*09a53ad8SAndrew Turner	bx	lr
134*09a53ad8SAndrew Turner
135*09a53ad8SAndrew Turner.Lmisaligned8:
136*09a53ad8SAndrew Turner	ldrd	data1a, data1b, [src]
137*09a53ad8SAndrew Turner	and	tmp2, tmp1, #3
138*09a53ad8SAndrew Turner	rsb	result, tmp1, #0
139*09a53ad8SAndrew Turner	lsl	tmp2, tmp2, #3			/* Bytes -> bits.  */
140*09a53ad8SAndrew Turner	tst	tmp1, #4
141*09a53ad8SAndrew Turner	pld	[src, #64]
142*09a53ad8SAndrew Turner	S2HI	tmp2, const_m1, tmp2
143*09a53ad8SAndrew Turner	orn	data1a, data1a, tmp2
144*09a53ad8SAndrew Turner	itt	ne
145*09a53ad8SAndrew Turner	ornne	data1b, data1b, tmp2
146*09a53ad8SAndrew Turner	movne	data1a, const_m1
147*09a53ad8SAndrew Turner	mov	const_0, #0
148*09a53ad8SAndrew Turner	b	.Lstart_realigned
149*09a53ad8SAndrew Turner	.size	strlen, . - strlen
150*09a53ad8SAndrew Turner
151