xref: /minix3/common/lib/libc/arch/arm/string/memcmp.S (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc/*      $NetBSD: memcmp.S,v 1.5 2015/03/26 13:34:51 justin Exp $ */
2b6cbf720SGianluca Guida
3b6cbf720SGianluca Guida/*
4b6cbf720SGianluca Guida * Copyright 2003 Wasabi Systems, Inc.
5b6cbf720SGianluca Guida * All rights reserved.
6b6cbf720SGianluca Guida *
7b6cbf720SGianluca Guida * Written by Steve C. Woodford for Wasabi Systems, Inc.
8b6cbf720SGianluca Guida *
9b6cbf720SGianluca Guida * Redistribution and use in source and binary forms, with or without
10b6cbf720SGianluca Guida * modification, are permitted provided that the following conditions
11b6cbf720SGianluca Guida * are met:
12b6cbf720SGianluca Guida * 1. Redistributions of source code must retain the above copyright
13b6cbf720SGianluca Guida *    notice, this list of conditions and the following disclaimer.
14b6cbf720SGianluca Guida * 2. Redistributions in binary form must reproduce the above copyright
15b6cbf720SGianluca Guida *    notice, this list of conditions and the following disclaimer in the
16b6cbf720SGianluca Guida *    documentation and/or other materials provided with the distribution.
17b6cbf720SGianluca Guida * 3. All advertising materials mentioning features or use of this software
18b6cbf720SGianluca Guida *    must display the following acknowledgement:
19b6cbf720SGianluca Guida *      This product includes software developed for the NetBSD Project by
20b6cbf720SGianluca Guida *      Wasabi Systems, Inc.
21b6cbf720SGianluca Guida * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22b6cbf720SGianluca Guida *    or promote products derived from this software without specific prior
23b6cbf720SGianluca Guida *    written permission.
24b6cbf720SGianluca Guida *
25b6cbf720SGianluca Guida * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26b6cbf720SGianluca Guida * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27b6cbf720SGianluca Guida * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28b6cbf720SGianluca Guida * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29b6cbf720SGianluca Guida * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30b6cbf720SGianluca Guida * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31b6cbf720SGianluca Guida * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32b6cbf720SGianluca Guida * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33b6cbf720SGianluca Guida * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34b6cbf720SGianluca Guida * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35b6cbf720SGianluca Guida * POSSIBILITY OF SUCH DAMAGE.
36b6cbf720SGianluca Guida */
37b6cbf720SGianluca Guida/*
38b6cbf720SGianluca Guida * Copyright (c) 2002 ARM Ltd
39b6cbf720SGianluca Guida * All rights reserved.
40b6cbf720SGianluca Guida *
41b6cbf720SGianluca Guida * Redistribution and use in source and binary forms, with or without
42b6cbf720SGianluca Guida * modification, are permitted provided that the following conditions
43b6cbf720SGianluca Guida * are met:
44b6cbf720SGianluca Guida * 1. Redistributions of source code must retain the above copyright
45b6cbf720SGianluca Guida *    notice, this list of conditions and the following disclaimer.
46b6cbf720SGianluca Guida * 2. Redistributions in binary form must reproduce the above copyright
47b6cbf720SGianluca Guida *    notice, this list of conditions and the following disclaimer in the
48b6cbf720SGianluca Guida *    documentation and/or other materials provided with the distribution.
49b6cbf720SGianluca Guida * 3. The name of the company may not be used to endorse or promote
50b6cbf720SGianluca Guida *    products derived from this software without specific prior written
51b6cbf720SGianluca Guida *    permission.
52b6cbf720SGianluca Guida *
53b6cbf720SGianluca Guida * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
54b6cbf720SGianluca Guida * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
55b6cbf720SGianluca Guida * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
56b6cbf720SGianluca Guida * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
57b6cbf720SGianluca Guida * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
58b6cbf720SGianluca Guida * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
59b6cbf720SGianluca Guida * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
60b6cbf720SGianluca Guida * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
61b6cbf720SGianluca Guida * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62b6cbf720SGianluca Guida * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63b6cbf720SGianluca Guida */
64b6cbf720SGianluca Guida
65b6cbf720SGianluca Guida#include <machine/asm.h>
66b6cbf720SGianluca Guida
67*0a6a1f1dSLionel SambucRCSID("$NetBSD: memcmp.S,v 1.5 2015/03/26 13:34:51 justin Exp $")
68b6cbf720SGianluca Guida
69b6cbf720SGianluca GuidaENTRY(memcmp)
70b6cbf720SGianluca Guida	mov	ip, r0
71b6cbf720SGianluca Guida#if defined(_KERNEL) && !defined(_STANDALONE)
72b6cbf720SGianluca Guida	cmp	r2, #0x06
73b6cbf720SGianluca Guida	beq	.Lmemcmp_6bytes
74b6cbf720SGianluca Guida#endif
75b6cbf720SGianluca Guida	mov	r0, #0x00
76b6cbf720SGianluca Guida
77b6cbf720SGianluca Guida	/* Are both addresses aligned the same way? */
78b6cbf720SGianluca Guida	cmp	r2, #0x00
7984d9c625SLionel Sambuc	eorsne	r3, ip, r1
80b6cbf720SGianluca Guida	RETc(eq)			/* len == 0, or same addresses! */
81b6cbf720SGianluca Guida	tst	r3, #0x03
82b6cbf720SGianluca Guida	subne	r2, r2, #0x01
83b6cbf720SGianluca Guida	bne	.Lmemcmp_bytewise2	/* Badly aligned. Do it the slow way */
84b6cbf720SGianluca Guida
85b6cbf720SGianluca Guida	/* Word-align the addresses, if necessary */
86b6cbf720SGianluca Guida	sub	r3, r1, #0x05
87b6cbf720SGianluca Guida	ands	r3, r3, #0x03
88b6cbf720SGianluca Guida	add	r3, r3, r3, lsl #1
89b6cbf720SGianluca Guida	addne	pc, pc, r3, lsl #3
90b6cbf720SGianluca Guida	nop
91b6cbf720SGianluca Guida
92b6cbf720SGianluca Guida	/* Compare up to 3 bytes */
93b6cbf720SGianluca Guida	ldrb	r0, [ip], #0x01
94b6cbf720SGianluca Guida	ldrb	r3, [r1], #0x01
95b6cbf720SGianluca Guida	subs	r0, r0, r3
96b6cbf720SGianluca Guida	RETc(ne)
97b6cbf720SGianluca Guida	subs	r2, r2, #0x01
98b6cbf720SGianluca Guida	RETc(eq)
99b6cbf720SGianluca Guida
100b6cbf720SGianluca Guida	/* Compare up to 2 bytes */
101b6cbf720SGianluca Guida	ldrb	r0, [ip], #0x01
102b6cbf720SGianluca Guida	ldrb	r3, [r1], #0x01
103b6cbf720SGianluca Guida	subs	r0, r0, r3
104b6cbf720SGianluca Guida	RETc(ne)
105b6cbf720SGianluca Guida	subs	r2, r2, #0x01
106b6cbf720SGianluca Guida	RETc(eq)
107b6cbf720SGianluca Guida
108b6cbf720SGianluca Guida	/* Compare 1 byte */
109b6cbf720SGianluca Guida	ldrb	r0, [ip], #0x01
110b6cbf720SGianluca Guida	ldrb	r3, [r1], #0x01
111b6cbf720SGianluca Guida	subs	r0, r0, r3
112b6cbf720SGianluca Guida	RETc(ne)
113b6cbf720SGianluca Guida	subs	r2, r2, #0x01
114b6cbf720SGianluca Guida	RETc(eq)
115b6cbf720SGianluca Guida
116b6cbf720SGianluca Guida	/* Compare 4 bytes at a time, if possible */
117b6cbf720SGianluca Guida	subs	r2, r2, #0x04
118b6cbf720SGianluca Guida	bcc	.Lmemcmp_bytewise
119b6cbf720SGianluca Guida.Lmemcmp_word_aligned:
120b6cbf720SGianluca Guida	ldr	r0, [ip], #0x04
121b6cbf720SGianluca Guida	ldr	r3, [r1], #0x04
122b6cbf720SGianluca Guida	subs	r2, r2, #0x04
123b6cbf720SGianluca Guida	cmpcs	r0, r3
124b6cbf720SGianluca Guida	beq	.Lmemcmp_word_aligned
125b6cbf720SGianluca Guida	sub	r0, r0, r3
126b6cbf720SGianluca Guida
127b6cbf720SGianluca Guida	/* Correct for extra subtraction, and check if done */
128b6cbf720SGianluca Guida	adds	r2, r2, #0x04
129b6cbf720SGianluca Guida	cmpeq	r0, #0x00		/* If done, did all bytes match? */
130b6cbf720SGianluca Guida	RETc(eq)			/* Yup. Just return */
131b6cbf720SGianluca Guida
132b6cbf720SGianluca Guida	/* Re-do the final word byte-wise */
133b6cbf720SGianluca Guida	sub	ip, ip, #0x04
134b6cbf720SGianluca Guida	sub	r1, r1, #0x04
135b6cbf720SGianluca Guida
136b6cbf720SGianluca Guida.Lmemcmp_bytewise:
137b6cbf720SGianluca Guida	add	r2, r2, #0x03
138b6cbf720SGianluca Guida.Lmemcmp_bytewise2:
139b6cbf720SGianluca Guida	ldrb	r0, [ip], #0x01
140b6cbf720SGianluca Guida	ldrb	r3, [r1], #0x01
141b6cbf720SGianluca Guida	subs	r2, r2, #0x01
142b6cbf720SGianluca Guida	cmpcs	r0, r3
143b6cbf720SGianluca Guida	beq	.Lmemcmp_bytewise2
144b6cbf720SGianluca Guida	sub	r0, r0, r3
145b6cbf720SGianluca Guida	RET
146b6cbf720SGianluca Guida
147b6cbf720SGianluca Guida#if defined(_KERNEL) && !defined(_STANDALONE)
148b6cbf720SGianluca Guida	/*
149b6cbf720SGianluca Guida	 * 6 byte compares are very common, thanks to the network stack.
150b6cbf720SGianluca Guida	 * This code is hand-scheduled to reduce the number of stalls for
151b6cbf720SGianluca Guida	 * load results. Everything else being equal, this will be ~32%
152b6cbf720SGianluca Guida	 * faster than a byte-wise memcmp.
153b6cbf720SGianluca Guida	 */
154b6cbf720SGianluca Guida	.align	5
155b6cbf720SGianluca Guida.Lmemcmp_6bytes:
156b6cbf720SGianluca Guida	ldrb	r3, [r1, #0x00]		/* r3 = b2#0 */
157b6cbf720SGianluca Guida	ldrb	r0, [ip, #0x00]		/* r0 = b1#0 */
158b6cbf720SGianluca Guida	ldrb	r2, [r1, #0x01]		/* r2 = b2#1 */
159b6cbf720SGianluca Guida	subs	r0, r0, r3		/* r0 = b1#0 - b2#0 */
16084d9c625SLionel Sambuc	ldrbeq	r3, [ip, #0x01]		/* r3 = b1#1 */
161b6cbf720SGianluca Guida	RETc(ne)			/* Return if mismatch on #0 */
162b6cbf720SGianluca Guida	subs	r0, r3, r2		/* r0 = b1#1 - b2#1 */
16384d9c625SLionel Sambuc	ldrbeq	r3, [r1, #0x02]		/* r3 = b2#2 */
16484d9c625SLionel Sambuc	ldrbeq	r0, [ip, #0x02]		/* r0 = b1#2 */
165b6cbf720SGianluca Guida	RETc(ne)			/* Return if mismatch on #1 */
166b6cbf720SGianluca Guida	ldrb	r2, [r1, #0x03]		/* r2 = b2#3 */
167b6cbf720SGianluca Guida	subs	r0, r0, r3		/* r0 = b1#2 - b2#2 */
16884d9c625SLionel Sambuc	ldrbeq	r3, [ip, #0x03]		/* r3 = b1#3 */
169b6cbf720SGianluca Guida	RETc(ne)			/* Return if mismatch on #2 */
170b6cbf720SGianluca Guida	subs	r0, r3, r2		/* r0 = b1#3 - b2#3 */
17184d9c625SLionel Sambuc	ldrbeq	r3, [r1, #0x04]		/* r3 = b2#4 */
17284d9c625SLionel Sambuc	ldrbeq	r0, [ip, #0x04]		/* r0 = b1#4 */
173b6cbf720SGianluca Guida	RETc(ne)			/* Return if mismatch on #3 */
174b6cbf720SGianluca Guida	ldrb	r2, [r1, #0x05]		/* r2 = b2#5 */
175b6cbf720SGianluca Guida	subs	r0, r0, r3		/* r0 = b1#4 - b2#4 */
17684d9c625SLionel Sambuc	ldrbeq	r3, [ip, #0x05]		/* r3 = b1#5 */
177b6cbf720SGianluca Guida	RETc(ne)			/* Return if mismatch on #4 */
178b6cbf720SGianluca Guida	sub	r0, r3, r2		/* r0 = b1#5 - b2#5 */
179b6cbf720SGianluca Guida	RET
180b6cbf720SGianluca Guida#endif
18184d9c625SLionel SambucEND(memcmp)
182*0a6a1f1dSLionel Sambuc
183*0a6a1f1dSLionel Sambuc#if defined(__ARM_EABI__) && !defined(_RUMPKERNEL)
184*0a6a1f1dSLionel SambucSTRONG_ALIAS(__aeabi_memcmp, memcmp)
185*0a6a1f1dSLionel Sambuc#endif
186