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