]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - lib/libc/arm/string/memcmp.S
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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 ENTRY(memcmp)
70         mov     ip, r0
71 #if defined(_KERNEL) && !defined(_STANDALONE)
72         cmp     r2, #0x06
73         beq     .Lmemcmp_6bytes
74 #endif
75         mov     r0, #0x00
76
77         /* Are both addresses aligned the same way? */
78         cmp     r2, #0x00
79         eornes  r3, ip, r1
80         RETeq                   /* len == 0, or same addresses! */
81         tst     r3, #0x03
82         subne   r2, r2, #0x01
83         bne     .Lmemcmp_bytewise2      /* Badly aligned. Do it the slow way */
84
85         /* Word-align the addresses, if necessary */
86         sub     r3, r1, #0x05
87         ands    r3, r3, #0x03
88         add     r3, r3, r3, lsl #1
89         addne   pc, pc, r3, lsl #3
90         nop
91
92         /* Compare up to 3 bytes */
93         ldrb    r0, [ip], #0x01
94         ldrb    r3, [r1], #0x01
95         subs    r0, r0, r3
96         RETne
97         subs    r2, r2, #0x01
98         RETeq
99
100         /* Compare up to 2 bytes */
101         ldrb    r0, [ip], #0x01
102         ldrb    r3, [r1], #0x01
103         subs    r0, r0, r3
104         RETne
105         subs    r2, r2, #0x01
106         RETeq
107
108         /* Compare 1 byte */
109         ldrb    r0, [ip], #0x01
110         ldrb    r3, [r1], #0x01
111         subs    r0, r0, r3
112         RETne
113         subs    r2, r2, #0x01
114         RETeq
115
116         /* Compare 4 bytes at a time, if possible */
117         subs    r2, r2, #0x04
118         bcc     .Lmemcmp_bytewise
119 .Lmemcmp_word_aligned:
120         ldr     r0, [ip], #0x04
121         ldr     r3, [r1], #0x04
122         subs    r2, r2, #0x04
123         cmpcs   r0, r3
124         beq     .Lmemcmp_word_aligned
125         sub     r0, r0, r3
126
127         /* Correct for extra subtraction, and check if done */
128         adds    r2, r2, #0x04
129         cmpeq   r0, #0x00               /* If done, did all bytes match? */
130         RETeq                   /* Yup. Just return */
131
132         /* Re-do the final word byte-wise */
133         sub     ip, ip, #0x04
134         sub     r1, r1, #0x04
135
136 .Lmemcmp_bytewise:
137         add     r2, r2, #0x03
138 .Lmemcmp_bytewise2:
139         ldrb    r0, [ip], #0x01
140         ldrb    r3, [r1], #0x01
141         subs    r2, r2, #0x01
142         cmpcs   r0, r3
143         beq     .Lmemcmp_bytewise2
144         sub     r0, r0, r3
145         RET
146
147 #if defined(_KERNEL) && !defined(_STANDALONE)
148         /*
149          * 6 byte compares are very common, thanks to the network stack.
150          * This code is hand-scheduled to reduce the number of stalls for
151          * load results. Everything else being equal, this will be ~32%
152          * faster than a byte-wise memcmp.
153          */
154         .align  5
155 .Lmemcmp_6bytes:
156         ldrb    r3, [r1, #0x00]         /* r3 = b2#0 */
157         ldrb    r0, [ip, #0x00]         /* r0 = b1#0 */
158         ldrb    r2, [r1, #0x01]         /* r2 = b2#1 */
159         subs    r0, r0, r3              /* r0 = b1#0 - b2#0 */
160         ldreqb  r3, [ip, #0x01]         /* r3 = b1#1 */
161         RETne                   /* Return if mismatch on #0 */
162         subs    r0, r3, r2              /* r0 = b1#1 - b2#1 */
163         ldreqb  r3, [r1, #0x02]         /* r3 = b2#2 */
164         ldreqb  r0, [ip, #0x02]         /* r0 = b1#2 */
165         RETne                   /* Return if mismatch on #1 */
166         ldrb    r2, [r1, #0x03]         /* r2 = b2#3 */
167         subs    r0, r0, r3              /* r0 = b1#2 - b2#2 */
168         ldreqb  r3, [ip, #0x03]         /* r3 = b1#3 */
169         RETne                   /* Return if mismatch on #2 */
170         subs    r0, r3, r2              /* r0 = b1#3 - b2#3 */
171         ldreqb  r3, [r1, #0x04]         /* r3 = b2#4 */
172         ldreqb  r0, [ip, #0x04]         /* r0 = b1#4 */
173         RETne                   /* Return if mismatch on #3 */
174         ldrb    r2, [r1, #0x05]         /* r2 = b2#5 */
175         subs    r0, r0, r3              /* r0 = b1#4 - b2#4 */
176         ldreqb  r3, [ip, #0x05]         /* r3 = b1#5 */
177         RETne                   /* Return if mismatch on #4 */
178         sub     r0, r3, r2              /* r0 = b1#5 - b2#5 */
179         RET
180 #endif