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