/* $NetBSD: memset.S,v 1.1 2020/08/16 06:43:43 isaki Exp $ */ /* * Copyright (C) 2020 Tetsuya Isaki. All rights reserved. * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Size optimized (but slow) version for primary bootloader. */ #include | | void bzero(void *dst, size_t len) | ASENTRY_NOPROFILE(bzero) moveml %sp@,%d0-%d1/%a1 | %d0: (return address) | %d1: dst | %a1: len subal %a0,%a0 | %a0: c = 0 jbra memset_common | | void *memset(void *dst, int c, size_t len); | ASENTRY_NOPROFILE(memset) moveml %sp@,%d0-%d1/%a0-%a1 | %d0: (return address) | %d1: dst | %a0: c | %a1: len memset_common: addal %d1,%a1 | %a1: loop start+1 address exg %d1,%a0 | %d1: c | %a0: initial dst | for return value and | loop-end condition address jbra 2f 1: moveb %d1,%a1@- | memset in reverse direction 2: cmpl %a1,%a0 jne 1b | if condition met, %a0 = dst rts #if defined(SELFTEST) #include "iocscall.h" .macro PRINT msg leal \msg,%a1 IOCS(__B_PRINT) .endm .macro TEST name leal \name,%a2 jbsr test .endm ASENTRY_NOPROFILE(selftest_memset) moveml %d2-%d7/%a2-%a6,%sp@- PRINT %pc@(msg_testname) TEST test1 TEST test2 PRINT %pc@(msg_crlf) moveml %sp@+,%d2-%d7/%a2-%a6 rts test: movel %a2@+,buf:W | initial contents of buffer movel %a2@+,%sp@- | push len movel %a2@+,%sp@- | push c movel %a2@+,%a3 | keep dst and movel %a3,%sp@- | push dst jbsr memset leal %sp@(12),%sp cmpal %a3,%a0 | compare return value jne fail movel %a2@+,%d0 | compare buf[0..4] cmpl buf:W,%d0 jne fail PRINT %pc@(msg_ok) rts fail: PRINT %pc@(msg_fail) rts test1: .long 0x11223344 | initial buf .long 2 | len .long 0xaa | c .long buf+1 | dst .long 0x11aaaa44 | expected buf test2: | len == 0 .long 0x11223344 | initial buf .long 0 | len .long 0x55 | c .long buf+1 | dst .long 0x11223344 | expected buf msg_testname: .asciz "memset" msg_ok: .asciz " ok" msg_fail: .asciz " fail" msg_crlf: .asciz "\r\n" BSS(buf, 8) #endif