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