[444] | 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 |
---|
| 21 | global _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 | |
---|
| 66 | testsrc: |
---|
| 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 */ |
---|
| 73 | even_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 | |
---|
| 82 | no_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 */ |
---|
| 91 | odd_copy: |
---|
| 92 | lddrb @rr6,@rr4,r3 |
---|
| 93 | |
---|
| 94 | finish: |
---|
| 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 | |
---|
| 144 | testsrc: |
---|
| 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 */ |
---|
| 151 | even_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 | |
---|
| 160 | no_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 */ |
---|
| 169 | odd_copy: |
---|
| 170 | lddrb @r7,@r6,r5 |
---|
| 171 | |
---|
| 172 | finish: |
---|
| 173 | #ifdef __STD_CALL__ |
---|
| 174 | ld r7,r15(#2) |
---|
| 175 | #endif |
---|
| 176 | |
---|
| 177 | #endif /* Z8002 */ |
---|
| 178 | |
---|
| 179 | ret |
---|
| 180 | .end |
---|