1/*- 2 * Copyright (c) 2018 Instituto de Pesquisas Eldorado 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the author nor the names of its contributors may 14 * be used to endorse or promote products derived from this software 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 */ 29 30#include <machine/asm.h> 31#ifndef FN_NAME 32#define FN_NAME __memcpy 33WEAK_REFERENCE(__memcpy, memcpy); 34#define BLOCK_BITS 4 35#endif 36 37#define BLOCK_BYTES (1 << BLOCK_BITS) 38#define BLOCK_MASK (BLOCK_BYTES - 1) 39 40/* Minimum 8 byte alignment, to avoid cache-inhibited alignment faults. */ 41#ifndef ALIGN_MASK 42#define ALIGN_MASK 0x7 43#endif 44 45/* 46 * r3: dst 47 * r4: src 48 * r5: len 49 */ 50ENTRY(FN_NAME) 51 cmpdi %r5, 0 /* len == 0? nothing to do */ 52 beqlr- 53 54 /* If src and dst are relatively misaligned, do byte copies. */ 55 andi. %r8, %r3, ALIGN_MASK 56 andi. %r7, %r4, ALIGN_MASK 57 cmpd %r8, %r7 58 mr %r7, %r5 59 mr %r8, %r3 /* save dst */ 60 bne .Lcopy_remaining_fix_index_byte 61 62 /* align src */ 63.Lalignment_loop: 64 lbz %r6, 0(%r4) 65 stb %r6, 0(%r3) 66 addi %r3, %r3, 1 67 addi %r4, %r4, 1 68 addi %r5, %r5, -1 69 cmpdi %r5, 0 70 beq .Lexit 71 andi. %r0, %r4, BLOCK_MASK 72 bne .Lalignment_loop 73 74 /* r7 = remaining, non-block, bytes */ 75 andi. %r7, %r5, BLOCK_MASK 76 77 /* Check if there are blocks of BLOCK_BYTES to be copied */ 78 xor. %r5, %r5, %r7 79 beq .Lcopy_remaining_fix_index_byte 80 81#ifdef FN_COPY_LOOP 82FN_COPY_LOOP 83#else 84 /* Setup to copy word with ldu and stdu */ 85 ld %r6, 0(%r4) 86 ld %r9, 8(%r4) 87 std %r6, 0(%r3) 88 std %r9, 8(%r3) 89 addi %r5, %r5, -BLOCK_BYTES 90 cmpd %r5, 0 91 beq .Lcopy_remaining_fix_index_word 92 93 srdi %r5, %r5, BLOCK_BITS 94 mtctr %r5 95.Lcopy_word: 96 ldu %r6, 16(%r4) 97 ld %r9, 8(%r4) 98 stdu %r6, 16(%r3) 99 std %r9, 8(%r3) 100 bdnz .Lcopy_word 101 102.Lcopy_remaining_fix_index_word: 103 /* Check if there are remaining bytes */ 104 cmpd %r7, 0 105 beq .Lexit 106 addi %r3, %r3, BLOCK_MASK 107 addi %r4, %r4, BLOCK_MASK 108 b .Lcopy_remaining 109#endif 110 111.Lcopy_remaining_fix_index_byte: 112 addi %r4, %r4, -1 113 addi %r3, %r3, -1 114 115 /* Copy remaining bytes */ 116.Lcopy_remaining: 117 mtctr %r7 118.Lcopy_remaining_loop: 119 lbzu %r6, 1(%r4) 120 stbu %r6, 1(%r3) 121 bdnz .Lcopy_remaining_loop 122 123.Lexit: 124 /* Restore dst */ 125 mr %r3, %r8 126 blr 127 128END(FN_NAME) 129 130 .section .note.GNU-stack,"",%progbits 131 132