1 1.6 macallan /* $NetBSD: memcpy.S,v 1.6 2014/03/04 17:05:14 macallan Exp $ */ 2 1.1 garbled 3 1.1 garbled /* stropt/memcpy_440.S, pl_string_common, pl_linux 10/11/04 11:45:36 4 1.1 garbled * ========================================================================== 5 1.1 garbled * Optimized memcpy implementation for IBM PowerPC 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: Copy n bytes of the source to the destination. Behavior is 41 1.1 garbled * undefined for objects that overlap. 42 1.1 garbled * 43 1.1 garbled * 44 1.1 garbled * void *memcpy(void * dest, const void * src, int n) 45 1.1 garbled * 46 1.1 garbled * Input: r3 - destination address 47 1.1 garbled * r4 - source address 48 1.1 garbled * r5 - byte count 49 1.1 garbled * Output: r3 - destination address 50 1.1 garbled * 51 1.1 garbled * ========================================================================== 52 1.1 garbled */ 53 1.1 garbled 54 1.1 garbled #include <machine/asm.h> 55 1.5 matt #ifdef _KERNEL_OPT 56 1.4 macallan #include "opt_ppcarch.h" 57 1.4 macallan #endif 58 1.1 garbled 59 1.1 garbled .text 60 1.1 garbled .align 4 61 1.1 garbled /* LINTSTUB: Func: void *memcpy(void *, const void *, size_t) */ 62 1.1 garbled ENTRY(memcpy) 63 1.1 garbled /* 64 1.1 garbled * Check count passed in R5. If zero, return; otherwise continue. 65 1.1 garbled */ 66 1.1 garbled cmpwi %r5,0 67 1.1 garbled beqlr- 68 1.1 garbled 69 1.4 macallan #if defined(_KERNEL) && defined(PPC_OEA601) 70 1.4 macallan /* 71 1.4 macallan * 601 will generate alignment exceptions if operand crosses 72 1.4 macallan * 4k page boundary, so do byte copy when exception handler 73 1.4 macallan * not available. Maybe want to have a different memcpy for 601 74 1.4 macallan * that checks for page boundaries/word alignment... 75 1.4 macallan */ 76 1.6 macallan mfspr %r6, 287 /* mfpvbr %r6 PVR = 287 */ 77 1.6 macallan srwi %r6, %r6, 0x10 /* get version field from PVR */ 78 1.6 macallan cmpwi %r6, 0x1 /* 601 CPU = 0x0001 */ 79 1.6 macallan bne bnorm /* skip byte-only unless 601 */ 80 1.6 macallan 81 1.6 macallan or %r6, %r3, %r4 /* see if both source and dest */ 82 1.6 macallan andi. %r6, %r6, 3 /* are 32bit aligned */ 83 1.6 macallan beq bnorm /* skip byte-only if they are */ 84 1.4 macallan bcpy: 85 1.4 macallan mtctr %r5 /* byte copy everything */ 86 1.4 macallan li %r6, 0 87 1.4 macallan bloop: 88 1.4 macallan lbzx %r7, %r4, %r6 89 1.4 macallan stbx %r7, %r3, %r6 90 1.4 macallan addi %r6, %r6, 1 91 1.4 macallan bdnz bloop 92 1.4 macallan blr 93 1.4 macallan 94 1.4 macallan bnorm: 95 1.4 macallan 96 1.4 macallan #endif 97 1.4 macallan 98 1.1 garbled mr %r8, %r3 /* Copy dst (return value) */ 99 1.1 garbled 100 1.1 garbled addi %r4, %r4, -4 /* Prepare for main loop's auto */ 101 1.1 garbled addi %r8, %r8, -4 /* update */ 102 1.1 garbled 103 1.1 garbled srwi. %r9,%r5,2 /* Word count -> r9 */ 104 1.1 garbled beq- last1 /* Partial copy if <4 bytes */ 105 1.1 garbled 106 1.1 garbled mtctr %r9 /* Word cnt in CTR for loop */ 107 1.1 garbled lwzu %r7, 4(%r4) /* Preload for main loop */ 108 1.1 garbled 109 1.1 garbled b g1 110 1.1 garbled 111 1.1 garbled g0: /* Main loop */ 112 1.1 garbled 113 1.1 garbled lwzu %r7, 4(%r4) /* Load a new word */ 114 1.1 garbled stwu %r6, 4(%r8) /* Store previous word */ 115 1.1 garbled 116 1.1 garbled g1: 117 1.1 garbled 118 1.1 garbled bdz- last /* Dec ctr and exit loop if no */ 119 1.1 garbled /* more words */ 120 1.1 garbled lwzu %r6, 4(%r4) /* Load another word */ 121 1.1 garbled stwu %r7, 4(%r8) /* Store previous word */ 122 1.1 garbled bdnz+ g0 /* Dec ctr and continue loop if */ 123 1.1 garbled /* more words */ 124 1.1 garbled 125 1.1 garbled mr %r7, %r6 126 1.1 garbled 127 1.1 garbled last: 128 1.1 garbled 129 1.1 garbled stwu %r7, 4(%r8) /* Store last word */ 130 1.1 garbled 131 1.1 garbled last1: /* Byte-by-byte copy */ 132 1.1 garbled 133 1.1 garbled clrlwi. %r5,%r5,30 134 1.1 garbled beqlr 135 1.1 garbled 136 1.1 garbled mtctr %r5 137 1.1 garbled 138 1.1 garbled lbzu %r6, 4(%r4) /* 1st byte: update by word */ 139 1.1 garbled stbu %r6, 4(%r8) 140 1.1 garbled bdzlr- 141 1.1 garbled 142 1.1 garbled last2: 143 1.1 garbled 144 1.1 garbled lbzu %r6, 1(%r4) /* Handle the rest */ 145 1.1 garbled stbu %r6, 1(%r8) 146 1.1 garbled bdnz+ last2 147 1.1 garbled 148 1.1 garbled blr 149 1.3 matt END(memcpy) 150