memcmp.S revision 1.2 1 /* $NetBSD: memcmp.S,v 1.2 2024/01/07 07:58:34 isaki Exp $ */
2
3 /*
4 * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
5 * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 /*
30 * Size optimized (but slow) version for primary bootloader.
31 */
32
33 #include <machine/asm.h>
34
35 |
36 | int memcmp(const void *b1, const void *b2, size_t len)
37 |
38 ASENTRY_NOPROFILE(memcmp)
39 moveml %sp@,%d0-%d1/%a0-%a1 | %d0: (return address)
40 | %d1: b1
41 | %a0: b2
42 | %a1: len
43
44 exg %d1,%a1 | %d1: len
45 | %a0: b2
46 | %a1: b1
47 moveql #0,%d0
48 loop:
49 subql #1,%d1 | if (--len < 0)
50 jcs exit | goto exit
51 compare:
52 cmpmb %a0@+,%a1@+
53 jeq loop
54 | To comply with standards, recalc exact return value.
55 | Although everyone expects only 0 or not...
56 moveq #0,%d1
57 moveb %a1@-,%d0
58 moveb %a0@-,%d1
59 subl %d1,%d0 | (uint)*b1 - (uint)*b2
60 exit:
61 rts
62
63
64 #if defined(SELFTEST)
65 #include "iocscall.h"
66 .macro PRINT msg
67 leal \msg,%a1
68 IOCS(__B_PRINT)
69 .endm
70
71 .macro TEST name
72 leal \name,%a2
73 jbsr test
74 .endm
75
76 ASENTRY_NOPROFILE(selftest_memcmp)
77 moveml %d2-%d7/%a2-%a6,%sp@-
78 PRINT %pc@(msg_testname)
79
80 TEST test1
81 TEST test2
82 TEST test3
83 TEST test4
84 TEST test5
85
86 PRINT %pc@(msg_crlf)
87 moveml %sp@+,%d2-%d7/%a2-%a6
88 rts
89
90 test:
91 movel %a2@+,buf:W | contents of b1
92 movel %a2@+,(buf+4):W | contents of b2
93 movel %a2@+,%sp@- | push len
94 peal (buf+4):W | push b2
95 peal (buf):W | push b1
96 jbsr memcmp
97 leal %sp@(12),%sp
98
99 cmpl %a2@,%d0 | compare return value
100 jne fail
101 PRINT %pc@(msg_ok)
102 rts
103 fail:
104 PRINT %pc@(msg_fail)
105 rts
106
107 test1:
108 | b1 == b2 within length
109 .long 0x11223344 | b1
110 .long 0x11223355 | b2
111 .long 3 | len
112 .long 0 | expected
113
114 test2:
115 | b1 > b2 before the last
116 .long 0x11813344 | b1
117 .long 0x11013344 | b2
118 .long 3 | len
119 .long 0x00000080 | expected
120
121 test3:
122 | b1 < b2 in the last byte
123 .long 0x11220044 | b1
124 .long 0x11220144 | b2
125 .long 3 | len
126 .long -1 | expected
127
128 test4: | len == 0
129 .long 0x11223344 | b1
130 .long 0x11223344 | b2
131 .long 0 | len
132 .long 0 | expected
133
134 test5: | *b1 - *b2 = 0 - 255 = -255
135 .long 0x00000000 | b1
136 .long 0xff000000 | b2
137 .long 1 | len
138 .long -255 | expected
139
140 msg_testname:
141 .asciz "memcmp"
142 msg_ok:
143 .asciz " ok"
144 msg_fail:
145 .asciz " fail"
146 msg_crlf:
147 .asciz "\r\n"
148
149 BSS(buf, 8)
150 #endif
151