1/* 2 * memcpy routine for Z8000 3 * Copyright (C) 2004 Christian Groessler <chris@groessler.org> 4 * 5 * Permission to use, copy, modify, and distribute this file 6 * for any purpose is hereby granted without fee, provided that 7 * the above copyright notice and this notice appears in all 8 * copies. 9 * 10 * This file is distributed WITHOUT ANY WARRANTY; without even the implied 11 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 */ 13 14/* void *memcpy(void *dest, const void *src, size_t length); 15 */ 16 17#include <picolibc.h> 18 19 name "memcpy.S" 20 21 .text 22 even 23global _memcpy 24global memmove_entry 25 26_memcpy: 27 28#ifdef __Z8001__ 29 segm 30 31#ifdef __STD_CALL__ 32 ldl rr6,rr14(#4) 33 ldl rr4,rr14(#8) 34 ldl rr2,rr14(#12) 35#else 36 pushl @rr14,rr6 37#endif 38 39/* rr2 - length (high word ignored) 40 * rr4 - src 41 * rr6 - dest 42 */ 43 44 testl rr2 45 jr z,finish 46 47memmove_entry: /* external entry point from memmove */ 48 49 bitb rl7,#0 /* odd destination address? */ 50 jr nz,testsrc 51 bitb rl5,#0 /* odd source address? */ 52 jr nz,odd_copy 53 jr t,even_copy /* dest even, src odd */ 54 55testsrc: 56 bitb rl5,#0 57 jr z,odd_copy /* src even, dest odd */ 58 ldib @rr6,@rr4,r3 59 jr ov,finish /* jump if r3 is zero now */ 60 61/* copy words */ 62even_copy: 63 ld r2,r3 /* remember length */ 64 srl r3,#1 65 jr z,no_words 66 67 ldir @rr6,@rr4,r3 68 69no_words: 70 bitb rl2,#0 /* odd length? */ 71 jr z,finish 72 ldib @rr6,@rr4,r2 /* yes, copy last byte */ 73 jr finish 74 75/* copy bytes */ 76odd_copy: 77 ldirb @rr6,@rr4,r3 78 79finish: 80#ifdef __STD_CALL__ 81 ldl rr6,rr14(#4) 82#else 83 popl rr2,@rr14 84#endif 85 86 87#else /* above Z8001, below Z8002 */ 88 89 90 unsegm 91 92#ifdef __STD_CALL__ 93 ld r7,r15(#2) 94 ld r6,r15(#4) 95 ld r5,r15(#6) 96#else 97 ld r2,r7 /* buffer pointer return value */ 98#endif 99 100/* r5 - length 101 * r6 - src 102 * r7 - dest 103 */ 104 test r5 105 jr z,finish 106 107memmove_entry: /* external entry point from memmove */ 108 109 bitb rl7,#0 /* odd destination address? */ 110 jr nz,testsrc 111 bitb rl6,#0 /* odd source address? */ 112 jr nz,odd_copy 113 jr t,even_copy /* dest even, src odd */ 114 115testsrc: 116 bitb rl6,#0 117 jr z,odd_copy /* src even, dest odd */ 118 ldib @r7,@r6,r5 119 jr ov,finish /* jump if r5 is zero now */ 120 121/* copy words */ 122even_copy: 123 ld r4,r5 /* remember length */ 124 srl r5,#1 125 jr z,no_words 126 127 ldir @r7,@r6,r5 128 129no_words: 130 bitb rl4,#0 /* odd length? */ 131 jr z,finish 132 ldib @r7,@r6,r4 /* yes, copy last byte */ 133 jr finish 134 135/* copy bytes */ 136odd_copy: 137 ldirb @r7,@r6,r5 138 139finish: 140#ifdef __STD_CALL__ 141 ld r7,r15(#2) 142#endif 143 144#endif /* Z8002 */ 145 146 ret 147 .end 148