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| 38ASENTRY_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 48loop: 49 subql #1,%d1 | if (--len < 0) 50 jcs exit | goto exit 51compare: 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 60exit: 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 76ASENTRY_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 90test: 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 103fail: 104 PRINT %pc@(msg_fail) 105 rts 106 107test1: 108 | b1 == b2 within length 109 .long 0x11223344 | b1 110 .long 0x11223355 | b2 111 .long 3 | len 112 .long 0 | expected 113 114test2: 115 | b1 > b2 before the last 116 .long 0x11813344 | b1 117 .long 0x11013344 | b2 118 .long 3 | len 119 .long 0x00000080 | expected 120 121test3: 122 | b1 < b2 in the last byte 123 .long 0x11220044 | b1 124 .long 0x11220144 | b2 125 .long 3 | len 126 .long -1 | expected 127 128test4: | len == 0 129 .long 0x11223344 | b1 130 .long 0x11223344 | b2 131 .long 0 | len 132 .long 0 | expected 133 134test5: | *b1 - *b2 = 0 - 255 = -255 135 .long 0x00000000 | b1 136 .long 0xff000000 | b2 137 .long 1 | len 138 .long -255 | expected 139 140msg_testname: 141 .asciz "memcmp" 142msg_ok: 143 .asciz " ok" 144msg_fail: 145 .asciz " fail" 146msg_crlf: 147 .asciz "\r\n" 148 149 BSS(buf, 8) 150#endif 151