1 1.3 matt /* $NetBSD: memmove.S,v 1.3 2011/01/15 07:31:12 matt Exp $ */ 2 1.1 garbled 3 1.1 garbled /* stropt/memmove.S, pl_string_common, pl_linux 10/11/04 11:45:37 4 1.1 garbled * ========================================================================== 5 1.1 garbled * Optimized memmove implementation for IBM PowerPC 405/440. 6 1.1 garbled * 7 1.1 garbled * Copyright (c) 2003, IBM Corporation 8 1.1 garbled * All rights reserved. 9 1.1 garbled * 10 1.1 garbled * Redistribution and use in source and binary forms, with or 11 1.1 garbled * without modification, are permitted provided that the following 12 1.1 garbled * conditions are met: 13 1.1 garbled * 14 1.1 garbled * * Redistributions of source code must retain the above 15 1.1 garbled * copyright notice, this list of conditions and the following 16 1.1 garbled * disclaimer. 17 1.1 garbled * * Redistributions in binary form must reproduce the above 18 1.1 garbled * copyright notice, this list of conditions and the following 19 1.1 garbled * disclaimer in the documentation and/or other materials 20 1.1 garbled * provided with the distribution. 21 1.1 garbled * * Neither the name of IBM nor the names of its contributors 22 1.1 garbled * may be used to endorse or promote products derived from this 23 1.1 garbled * software without specific prior written permission. 24 1.1 garbled * 25 1.1 garbled * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 26 1.1 garbled * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 27 1.1 garbled * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 1.1 garbled * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 29 1.1 garbled * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 30 1.1 garbled * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 31 1.1 garbled * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 1.1 garbled * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 1.1 garbled * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 34 1.1 garbled * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 1.1 garbled * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 36 1.1 garbled * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 1.1 garbled * 38 1.1 garbled * ========================================================================== 39 1.1 garbled * 40 1.1 garbled * Function: Move memory area (handles overlapping regions) 41 1.1 garbled * 42 1.1 garbled * void *memmove(void * dest, const void * src, int n) 43 1.1 garbled * 44 1.1 garbled * Input: r3 - destination address 45 1.1 garbled * r4 - source address 46 1.1 garbled * r5 - byte count 47 1.1 garbled * Output: r3 - destination address 48 1.1 garbled * 49 1.1 garbled * ========================================================================== 50 1.1 garbled */ 51 1.1 garbled 52 1.1 garbled #include <machine/asm.h> 53 1.1 garbled 54 1.1 garbled .text 55 1.1 garbled .align 4 56 1.1 garbled #ifdef _BCOPY 57 1.1 garbled /* bcopy = memcpy/memmove with arguments reversed. */ 58 1.1 garbled /* LINTSTUB: Func: void bcopy(void *, void *, size_t) */ 59 1.1 garbled ENTRY(bcopy) 60 1.1 garbled mr %r6, %r3 /* swap src/dst */ 61 1.1 garbled mr %r3, %r4 62 1.1 garbled mr %r4, %r6 63 1.1 garbled #else 64 1.1 garbled /* LINTSTUB: Func: void *memmove(void *, const void *, size_t) */ 65 1.1 garbled ENTRY(memmove) 66 1.1 garbled #endif 67 1.1 garbled 68 1.1 garbled mr %r8, %r3 /* Save dst (return value) */ 69 1.1 garbled 70 1.1 garbled cmpw %r4, %r8 /* Branch to reverse if */ 71 1.1 garbled blt reverse /* src < dest. Don't want to */ 72 1.1 garbled /* overwrite end of src with */ 73 1.1 garbled /* start of dest */ 74 1.1 garbled 75 1.1 garbled addi %r4, %r4, -4 /* Back up src and dst pointers */ 76 1.1 garbled addi %r8, %r8, -4 /* due to auto-update of 'load' */ 77 1.1 garbled 78 1.1 garbled srwi. %r9,%r5,2 /* How many words in total cnt */ 79 1.1 garbled beq- last1 /* Handle byte by byte if < 4 */ 80 1.1 garbled /* bytes total */ 81 1.1 garbled mtctr %r9 /* Count of words for loop */ 82 1.1 garbled lwzu %r7, 4(%r4) /* Preload first word */ 83 1.1 garbled 84 1.1 garbled b g1 85 1.1 garbled 86 1.1 garbled g0: /* Main loop */ 87 1.1 garbled 88 1.1 garbled lwzu %r7, 4(%r4) /* Load a new word */ 89 1.1 garbled stwu %r6, 4(%r8) /* Store previous word */ 90 1.1 garbled 91 1.1 garbled g1: 92 1.1 garbled 93 1.1 garbled bdz- last /* Dec cnt, and branch if just */ 94 1.1 garbled /* one word to store */ 95 1.1 garbled lwzu %r6, 4(%r4) /* Load another word */ 96 1.1 garbled stwu %r7, 4(%r8) /* Store previous word */ 97 1.1 garbled bdnz+ g0 /* Dec cnt, and loop again if */ 98 1.1 garbled /* more words */ 99 1.1 garbled mr %r7, %r6 /* If word count -> 0, then... */ 100 1.1 garbled 101 1.1 garbled last: 102 1.1 garbled 103 1.1 garbled stwu %r7, 4(%r8) /* ... store last word */ 104 1.1 garbled 105 1.1 garbled last1: /* Byte-by-byte copy */ 106 1.1 garbled 107 1.1 garbled clrlwi. %r5,%r5,30 /* If count -> 0, then ... */ 108 1.1 garbled beqlr /* we're done */ 109 1.1 garbled 110 1.1 garbled mtctr %r5 /* else load count for loop */ 111 1.1 garbled 112 1.1 garbled lbzu %r6, 4(%r4) /* 1st byte: update addr by 4 */ 113 1.1 garbled stbu %r6, 4(%r8) /* since we pre-adjusted by 4 */ 114 1.1 garbled bdzlr- /* in anticipation of main loop */ 115 1.1 garbled 116 1.1 garbled last2: 117 1.1 garbled 118 1.1 garbled lbzu %r6, 1(%r4) /* But handle the rest by */ 119 1.1 garbled stbu %r6, 1(%r8) /* updating addr by 1 */ 120 1.1 garbled bdnz+ last2 121 1.1 garbled 122 1.1 garbled blr 123 1.1 garbled 124 1.1 garbled /* We're here since src < dest. Don't want to overwrite end of */ 125 1.1 garbled /* src with start of dest */ 126 1.1 garbled 127 1.1 garbled reverse: 128 1.1 garbled 129 1.1 garbled add %r4, %r4, %r5 /* Work from end to beginning */ 130 1.1 garbled add %r8, %r8, %r5 /* so add count to string ptrs */ 131 1.1 garbled srwi. %r9,%r5,2 /* Words in total count */ 132 1.1 garbled beq- rlast1 /* Handle byte by byte if < 4 */ 133 1.1 garbled /* bytes total */ 134 1.1 garbled 135 1.1 garbled mtctr %r9 /* Count of words for loop */ 136 1.1 garbled 137 1.1 garbled lwzu %r7, -4(%r4) /* Preload first word */ 138 1.1 garbled b rg1 139 1.1 garbled 140 1.1 garbled rg0: /* Main loop */ 141 1.1 garbled 142 1.1 garbled lwzu %r7, -4(%r4) /* Load a new word */ 143 1.1 garbled stwu %r6, -4(%r8) /* Store previous word */ 144 1.1 garbled 145 1.1 garbled rg1: 146 1.1 garbled 147 1.1 garbled bdz- rlast /* Dec cnt, and branch if just */ 148 1.1 garbled /* one word to store */ 149 1.1 garbled 150 1.1 garbled lwzu %r6, -4(%r4) /* Load another word */ 151 1.1 garbled stwu %r7, -4(%r8) /* Store previous word */ 152 1.1 garbled 153 1.1 garbled bdnz+ rg0 /* Dec cnt, and loop again if */ 154 1.1 garbled /* more words */ 155 1.1 garbled 156 1.1 garbled mr %r7, %r6 /* If word count -> 0, then... */ 157 1.1 garbled 158 1.1 garbled rlast: 159 1.1 garbled 160 1.1 garbled stwu %r7, -4(%r8) /* ... store last word */ 161 1.1 garbled 162 1.1 garbled rlast1: /* Byte-by-byte copy */ 163 1.1 garbled 164 1.1 garbled clrlwi. %r5,%r5,30 /* If count -> 0, then... */ 165 1.1 garbled beqlr /* ... we're done */ 166 1.1 garbled 167 1.1 garbled mtctr %r5 /* else load count for loop */ 168 1.1 garbled 169 1.1 garbled rlast2: 170 1.1 garbled 171 1.1 garbled lbzu %r6, -1(%r4) /* Handle the rest, byte by */ 172 1.1 garbled stbu %r6, -1(%r8) /* byte */ 173 1.1 garbled 174 1.1 garbled bdnz+ rlast2 /* Dec ctr, and branch if more */ 175 1.1 garbled /* bytes left */ 176 1.1 garbled blr 177 1.1 garbled 178 1.3 matt #ifdef _BCOPY 179 1.3 matt END(bcopy) 180 1.3 matt #else 181 1.3 matt END(memmove) 182 1.3 matt #endif 183