1/* 2 * memmove 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 *memmove(void *dest, const void *src, size_t length); 15 */ 16 17 name "memmove.S" 18 19 .text 20 even 21global _memmove 22 23_memmove: 24 25#ifdef __Z8001__ 26 segm 27 28#ifdef __STD_CALL__ 29 ldl rr6,rr14(#4) 30 ldl rr4,rr14(#8) 31 ldl rr2,rr14(#12) 32#else 33 pushl @rr14,rr6 34#endif 35 36/* rr2 - length (high word ignored) 37 * rr4 - src 38 * rr6 - dest 39 */ 40 41 testl rr2 42 jr z,finish 43 44/* check for destructive overlap (src < dest && dest < src + length) */ 45 46 cpl rr6,rr4 47 jp ule,memmove_entry /* non-destructive, let memcpy do the work */ 48 ldl rr0,rr2 49 addl rr0,rr4 /* rr0 = src + length */ 50 cpl rr0,rr6 51 jp ult,memmove_entry /* non-destructive, let memcpy do the work */ 52 53/* set-up pointers to copy backwards, add (length - 1) */ 54 addl rr4,rr2 /* src + length */ 55 addl rr6,rr2 /* dest + length */ 56 subl rr4,#1 57 subl rr6,#1 58 59/* check alignment */ 60 bitb rl7,#0 /* odd destination address? */ 61 jr z,testsrc 62 bitb rl5,#0 /* odd source address? */ 63 jr z,odd_copy 64 jr even_copy 65 66testsrc: 67 bitb rl5,#0 68 jr nz,odd_copy /* src even, dest odd */ 69 lddb @rr6,@rr4,r3 70 jr ov,finish /* jump if r5 is zero now */ 71 72/* copy words */ 73even_copy: 74 ld r2,r3 /* remember length */ 75 srl r3,#1 76/* jr z,no_words it cannot be zero here */ 77 78 dec r5,#1 79 dec r7,#1 80 lddr @rr6,@rr4,r3 81 82no_words: 83 bitb rl2,#0 /* odd length? */ 84 jr z,finish 85 inc r5,#1 86 inc r7,#1 87 lddb @rr6,@rr4,r2 /* yes, copy last byte */ 88 jr finish 89 90/* copy bytes */ 91odd_copy: 92 lddrb @rr6,@rr4,r3 93 94finish: 95#ifdef __STD_CALL__ 96 ldl rr6,rr14(#4) 97#else 98 popl rr2,@rr14 99#endif 100 101 102#else /* above Z8001, below Z8002 */ 103 104 105 unsegm 106 107#ifdef __STD_CALL__ 108 ld r7,r15(#2) 109 ld r6,r15(#4) 110 ld r5,r15(#6) 111#else 112 ld r2,r7 /* buffer pointer return value */ 113#endif 114 115/* r5 - length 116 * r6 - src 117 * r7 - dest 118 */ 119 test r5 120 jr z,finish 121 122/* check for destructive overlap (src < dest && dest < src + length) */ 123 124 cp r7,r6 125 jp ule,memmove_entry /* non-destructive, let memcpy do the work */ 126 ld r0,r5 127 add r0,r6 /* r0 = src + length */ 128 cp r0,r7 129 jp ult,memmove_entry /* non-destructive, let memcpy do the work */ 130 131/* set-up pointers to copy backwards, add (length - 1) */ 132 add r6,r5 /* src + length */ 133 add r7,r5 /* dest + length */ 134 dec r6,#1 135 dec r7,#1 136 137/* check alignment */ 138 bitb rl7,#0 /* odd destination address? */ 139 jr z,testsrc 140 bitb rl6,#0 /* odd source address? */ 141 jr z,odd_copy 142 jr even_copy 143 144testsrc: 145 bitb rl6,#0 146 jr nz,odd_copy /* src even, dest odd */ 147 lddb @r7,@r6,r5 148 jr ov,finish /* jump if r5 is zero now */ 149 150/* copy words */ 151even_copy: 152 ld r4,r5 /* remember length */ 153 srl r5,#1 154/* jr z,no_words it cannot be zero here */ 155 156 dec r6,#1 157 dec r7,#1 158 lddr @r7,@r6,r5 159 160no_words: 161 bitb rl4,#0 /* odd length? */ 162 jr z,finish 163 inc r6,#1 164 inc r7,#1 165 lddb @r7,@r6,r4 /* yes, copy last byte */ 166 jr finish 167 168/* copy bytes */ 169odd_copy: 170 lddrb @r7,@r6,r5 171 172finish: 173#ifdef __STD_CALL__ 174 ld r7,r15(#2) 175#endif 176 177#endif /* Z8002 */ 178 179 ret 180 .end 181