11.1Sisaki/* $NetBSD: memcpy.S,v 1.1 2020/08/16 06:43:43 isaki Exp $ */ 21.1Sisaki 31.1Sisaki/* 41.1Sisaki * Copyright (C) 2020 Tetsuya Isaki. All rights reserved. 51.1Sisaki * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved. 61.1Sisaki * 71.1Sisaki * Redistribution and use in source and binary forms, with or without 81.1Sisaki * modification, are permitted provided that the following conditions 91.1Sisaki * are met: 101.1Sisaki * 1. Redistributions of source code must retain the above copyright 111.1Sisaki * notice, this list of conditions and the following disclaimer. 121.1Sisaki * 2. Redistributions in binary form must reproduce the above copyright 131.1Sisaki * notice, this list of conditions and the following disclaimer in the 141.1Sisaki * documentation and/or other materials provided with the distribution. 151.1Sisaki * 161.1Sisaki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 171.1Sisaki * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 181.1Sisaki * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 191.1Sisaki * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 201.1Sisaki * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 211.1Sisaki * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 221.1Sisaki * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 231.1Sisaki * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 241.1Sisaki * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 251.1Sisaki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 261.1Sisaki * SUCH DAMAGE. 271.1Sisaki */ 281.1Sisaki 291.1Sisaki/* 301.1Sisaki * Size optimized (but slow) version for primary bootloader. 311.1Sisaki */ 321.1Sisaki 331.1Sisaki#include <machine/asm.h> 341.1Sisaki 351.1Sisaki| 361.1Sisaki| void bcopy(const void *src, void *dst, size_t len); 371.1Sisaki| 381.1SisakiASENTRY_NOPROFILE(bcopy) 391.1Sisaki moveml %sp@,%d0-%d1/%a0-%a1 | %d0: (return address) 401.1Sisaki | %d1: src 411.1Sisaki | %a0: dst 421.1Sisaki | %a1: count 431.1Sisaki jbra memmove_common 441.1Sisaki| 451.1Sisaki| void *memcpy(void *dst, const void *src, size_t count); 461.1Sisaki| void *memmove(void *dst, const void *src, size_t count); 471.1Sisaki| 481.1SisakiASENTRY_NOPROFILE(memcpy) 491.1SisakiASENTRY_NOPROFILE(memmove) 501.1Sisaki moveml %sp@,%d0-%d1/%a0-%a1 | %d0: (return address) 511.1Sisaki | %d1: dst 521.1Sisaki | %a0: src 531.1Sisaki | %a1: count 541.1Sisaki 551.1Sisaki exg %d1,%a0 | %d1: src 561.1Sisaki | %a0: dst 571.1Sisaki | %a1: count 581.1Sisakimemmove_common: 591.1Sisaki exg %d1,%a1 | %d1: count 601.1Sisaki | %a0: dst 611.1Sisaki | %a1: src 621.1Sisaki moveql #0,%d0 631.1Sisaki | %d0: offset in forward mode. 641.1Sisaki | %d1: offset in backward mode 651.1Sisaki | and also loop counter. 661.1Sisaki jbra 2f 671.1Sisakiloop: 681.1Sisaki | if src(=%a1) > dst(=%a0), then this is forward copy, 691.1Sisaki | %d0 is already forward offset. 701.1Sisaki | Otherwise backward copy. Copy %d1(backward offset) to %d0. 711.1Sisaki cmpl %a1,%a0 721.1Sisaki jcs 1f 731.1Sisaki movel %d1,%d0 741.1Sisaki1: 751.1Sisaki moveb %a1@(%d0.l),%a0@(%d0.l) | %d0: offset 761.1Sisaki addql #1,%d0 | increment forward counter, 771.1Sisaki | though it's pointless in 781.1Sisaki | backward mode 791.1Sisaki2: 801.1Sisaki subql #1,%d1 | if (--count < 0) 811.1Sisaki jcc loop | goto exit 821.1Sisakiexit: 831.1Sisaki rts | %a0 holds return value (=dst) 841.1Sisaki 851.1Sisaki 861.1Sisaki#if defined(SELFTEST) 871.1Sisaki#include "iocscall.h" 881.1Sisaki .macro PRINT msg 891.1Sisaki leal \msg,%a1 901.1Sisaki IOCS(__B_PRINT) 911.1Sisaki .endm 921.1Sisaki 931.1Sisaki .macro TEST name 941.1Sisaki leal \name,%a2 951.1Sisaki jbsr test 961.1Sisaki .endm 971.1Sisaki 981.1SisakiASENTRY_NOPROFILE(selftest_memmove) 991.1Sisaki moveml %d2-%d7/%a2-%a6,%sp@- 1001.1Sisaki PRINT %pc@(msg_testname) 1011.1Sisaki 1021.1Sisaki TEST test1 1031.1Sisaki TEST test2 1041.1Sisaki TEST test3 1051.1Sisaki TEST test4 1061.1Sisaki 1071.1Sisaki PRINT %pc@(msg_crlf) 1081.1Sisaki moveml %sp@+,%d2-%d7/%a2-%a6 1091.1Sisaki rts 1101.1Sisaki 1111.1Sisakitest: 1121.1Sisaki movel %a2@+,buf:W | initial contents of buffer 1131.1Sisaki movew %a2@+,(buf+4):W | (6 bytes total) 1141.1Sisaki movel %a2@+,%sp@- | push len 1151.1Sisaki movel %a2@+,%sp@- | push src 1161.1Sisaki movel %a2@+,%a3 | keep dst and 1171.1Sisaki movel %a3,%sp@- | push dst 1181.1Sisaki jbsr memmove 1191.1Sisaki leal %sp@(12),%sp 1201.1Sisaki 1211.1Sisaki cmpal %a3,%a0 | compare return value 1221.1Sisaki jne fail 1231.1Sisaki movel %a2@+,%d0 | compare buf[0..3] 1241.1Sisaki cmpl buf:W,%d0 1251.1Sisaki jne fail 1261.1Sisaki movew %a2@+,%d0 | compare buf[4..5] 1271.1Sisaki cmpw (buf+4):W,%d0 | compare buf[4..5] 1281.1Sisaki jne fail 1291.1Sisaki PRINT %pc@(msg_ok) 1301.1Sisaki rts 1311.1Sisakifail: 1321.1Sisaki PRINT %pc@(msg_fail) 1331.1Sisaki rts 1341.1Sisaki 1351.1Sisakitest1: 1361.1Sisaki | src=buf+1: 1 2 3 4 5 6 1371.1Sisaki | \ \ 1381.1Sisaki | dst=buf+2: 1 2 2 3 5 6 1391.1Sisaki .byte 1, 2, 3, 4, 5, 6 | initial buf 1401.1Sisaki .long 2 | len 1411.1Sisaki .long buf+1 | src 1421.1Sisaki .long buf+2 | dst 1431.1Sisaki .byte 1, 2, 2, 3, 5, 6 | expected buf 1441.1Sisaki 1451.1Sisakitest2: 1461.1Sisaki | src=buf+2: 1 2 3 4 5 6 1471.1Sisaki | / / 1481.1Sisaki | dst=buf+1: 1 3 4 4 5 6 1491.1Sisaki .byte 1, 2, 3, 4, 5, 6 | initial buf 1501.1Sisaki .long 2 | len 1511.1Sisaki .long buf+2 | src 1521.1Sisaki .long buf+1 | dst 1531.1Sisaki .byte 1, 3, 4, 4, 5, 6 | expected buf 1541.1Sisaki 1551.1Sisakitest3: 1561.1Sisaki | src == dst 1571.1Sisaki .byte 1, 2, 3, 4, 5, 6 | initial buf 1581.1Sisaki .long 2 | len 1591.1Sisaki .long buf+1 | src 1601.1Sisaki .long buf+1 | dst 1611.1Sisaki .byte 1, 2, 3, 4, 5, 6 | expected buf 1621.1Sisaki 1631.1Sisakitest4: 1641.1Sisaki | len == 0 1651.1Sisaki .byte 1, 2, 3, 4, 5, 6 | initial buf 1661.1Sisaki .long 0 | len 1671.1Sisaki .long buf+1 | src 1681.1Sisaki .long buf+1 | dst 1691.1Sisaki .byte 1, 2, 3, 4, 5, 6 | expected buf 1701.1Sisaki 1711.1Sisakimsg_testname: 1721.1Sisaki .asciz "memmove" 1731.1Sisakimsg_ok: 1741.1Sisaki .asciz " ok" 1751.1Sisakimsg_fail: 1761.1Sisaki .asciz " fail" 1771.1Sisakimsg_crlf: 1781.1Sisaki .asciz "\r\n" 1791.1Sisaki 1801.1Sisaki BSS(buf, 8) 1811.1Sisaki#endif 182