1/*        $NetBSD: bcmp.S,v 1.6 2013/09/07 19:06:29 chs Exp $         */
2
3/*-
4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by J.T. Conklin.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*-
33 * Copyright (c) 1990 The Regents of the University of California.
34 * All rights reserved.
35 *
36 * This code is derived from software contributed to Berkeley by
37 * the Systems Programming Group of the University of Utah Computer
38 * Science Department.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 *    notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 *    notice, this list of conditions and the following disclaimer in the
47 *    documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors
49 *    may be used to endorse or promote products derived from this software
50 *    without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 */
64
65#include <machine/asm.h>
66
67#if defined(LIBC_SCCS) && !defined(lint)
68#if 0
69          RCSID("from: @(#)bcmp.s 5.1 (Berkeley) 5/12/90")
70#else
71          RCSID("$NetBSD: bcmp.S,v 1.6 2013/09/07 19:06:29 chs Exp $")
72#endif
73#endif /* LIBC_SCCS and not lint */
74
75#ifdef __mcoldfire__
76#define   CMPMB(a,b)          movb b,%d2; cmpb a,%d2
77#define   CMPMW(a,b)          movw b,%d2; cmpw a,%d2
78#define   CMPML(a,b)          movl b,%d2; cmpl a,%d2
79#else
80#define   CMPMB(a,b)          cmpmb a,b
81#define   CMPMW(a,b)          cmpmw a,b
82#define   CMPML(a,b)          cmpml a,b
83#endif
84
85ENTRY(bcmp)
86          movl      4(%sp),%a0                    | string 1
87          movl      8(%sp),%a1                    | string 2
88          movl      12(%sp),%d1                   | length
89#ifdef __mcoldfire__
90          movl      %d2,-(%sp)                    | save temp
91#endif
92
93          /*
94           * It isn't worth the overhead of aligning to {long}word boundries
95           * if the string is too short.
96           */
97          cmpl      #8,%d1
98          jlt       .Lbcbyte
99
100#ifdef    __mc68010__
101          /*
102           * The 68010 cannot access a word or long on an odd boundary,
103           * period.  If the source and the destination addresses aren't
104           * of the same evenness, we're forced to do a bytewise compare.
105           */
106          movl      %a0,%d0
107          addl      %a1,%d0
108          btst      #0,%d0
109          jne       .Lbcbyte
110#endif    /* __mc68010__ */
111
112          /* word align */
113          movl      %a0,%d0
114          btst      #0,%d0
115          jeq       .Lbcalgndw
116          CMPMB((%a0)+,(%a1)+)
117          jne       .Lbcnoteq
118          subql     #1,%d1
119.Lbcalgndw:
120          /* long word align */
121          btst      #1,%d0
122          jeq       .Lbcalgndl
123          CMPMW((%a0)+,(%a1)+)
124          jne       .Lbcnoteq
125          subql     #2,%d1
126.Lbcalgndl:
127          /* compare by 8 longwords */
128          movl      %d1,%d0
129          lsrl      #5,%d0                        | cnt = len / 32
130          jeq       .Lbclong                      | if (cnt)
131          andl      #31,%d1                       |         len %= 32
132          subql     #1,%d0                        |         set up for dbf
133.Lbc32loop:
134          CMPML((%a0)+,(%a1)+)                    |         compare 1 of 8 longwords
135          jne       .Lbcnoteq           |         not equal, return non-zero
136          CMPML((%a0)+,(%a1)+)                    |         compare 2 of 8 longwords
137          jne       .Lbcnoteq
138          CMPML((%a0)+,(%a1)+)                    |         compare 3 of 8 longwords
139          jne       .Lbcnoteq
140          CMPML((%a0)+,(%a1)+)                    |         compare 4 of 8 longwords
141          jne       .Lbcnoteq
142          CMPML((%a0)+,(%a1)+)                    |         compare 5 of 8 longwords
143          jne       .Lbcnoteq
144          CMPML((%a0)+,(%a1)+)                    |         compare 6 of 8 longwords
145          jne       .Lbcnoteq
146          CMPML((%a0)+,(%a1)+)                    |         compare 7 of 8 longwords
147          jne       .Lbcnoteq
148          CMPML((%a0)+,(%a1)+)                    |         compare 8 of 8 longwords
149          jne       .Lbcnoteq
150#ifndef __mcoldfire__
151          dbf       %d0,.Lbc32loop                |         till done
152          clrw      %d0
153#endif
154          subql     #1,%d0
155          jcc       .Lbc32loop
156
157.Lbclong:
158          /* compare by longwords */
159          movl      %d1,%d0
160          lsrl      #2,%d0                        | cnt = len / 4
161          jeq       .Lbcbyte                      | if (cnt)
162          subql     #1,%d0                        |         set up for dbf
163.Lbclloop:
164          CMPML((%a0)+,(%a1)+)                    |         compare a longword
165          jne       .Lbcnoteq           |         not equal, return non-zero
166#ifdef __mcoldfire__
167          subql     #1,%d0                        |         decrement
168          jcc       .Lbclloop           |         till done
169#else
170          dbf       %d0,.Lbclloop                 |         till done
171#endif
172          andl      #3,%d1                        |         len %= 4
173          jeq       .Lbcdone
174
175          subql     #1,%d1                        | set up for dbf
176.Lbcbloop:
177          CMPMB((%a0)+,(%a1)+)                    | compare a byte
178          jne       .Lbcnoteq           | not equal, return non-zero
179.Lbcbyte:
180#ifdef __mcoldfire__
181          subql     #1,%d0                        |         decrement
182          jcc       .Lbcbloop           |         till done
183#else
184          dbf       %d1,.Lbcbloop
185#endif
186.Lbcdone:
187#ifdef __mcoldfire__
188          movl      (%sp)+,%d2                    | restore temp
189#endif
190          movql     #0,%d0
191          rts
192
193.Lbcnoteq:
194          movql     #1,%d0
195          rts
196END(bcmp)
197