Home | History | Annotate | Line # | Download | only in xxboot
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