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__FBSDID("$FreeBSD$"); 32 33#ifndef FN_NAME 34#define FN_NAME __memcpy 35WEAK_REFERENCE(__memcpy, memcpy); 36#define BLOCK_BITS 4 37#endif 38 39#define BLOCK_BYTES (1 << BLOCK_BITS) 40#define BLOCK_MASK (BLOCK_BYTES - 1) 41 42/* 43 * r3: dst 44 * r4: src 45 * r5: len 46 */ 47ENTRY(FN_NAME) 48 cmpdi %r5, 0 /* len == 0? nothing to do */ 49 beqlr- 50 51 mr %r8, %r3 /* save dst */ 52 53 /* align src */ 54.Lalignment_loop: 55 lbz %r6, 0(%r4) 56 stb %r6, 0(%r3) 57 addi %r3, %r3, 1 58 addi %r4, %r4, 1 59 addi %r5, %r5, -1 60 cmpdi %r5, 0 61 beq .Lexit 62 andi. %r0, %r4, BLOCK_MASK 63 bne .Lalignment_loop 64 65 /* r7 = remaining, non-block, bytes */ 66 andi. %r7, %r5, BLOCK_MASK 67 68 /* Check if there are blocks of BLOCK_BYTES to be copied */ 69 xor. %r5, %r5, %r7 70 beq .Lcopy_remaining_fix_index_byte 71 72#ifdef FN_COPY_LOOP 73FN_COPY_LOOP 74#else 75 /* Setup to copy word with ldu and stdu */ 76 ld %r6, 0(%r4) 77 ld %r9, 8(%r4) 78 std %r6, 0(%r3) 79 std %r9, 8(%r3) 80 addi %r5, %r5, -BLOCK_BYTES 81 cmpd %r5, 0 82 beq .Lcopy_remaining_fix_index_word 83 84 srdi %r5, %r5, BLOCK_BITS 85 mtctr %r5 86.Lcopy_word: 87 ldu %r6, 16(%r4) 88 ld %r9, 8(%r4) 89 stdu %r6, 16(%r3) 90 std %r9, 8(%r3) 91 bdnz .Lcopy_word 92 93.Lcopy_remaining_fix_index_word: 94 /* Check if there are remaining bytes */ 95 cmpd %r7, 0 96 beq .Lexit 97 addi %r3, %r3, BLOCK_MASK 98 addi %r4, %r4, BLOCK_MASK 99 b .Lcopy_remaining 100#endif 101 102.Lcopy_remaining_fix_index_byte: 103 addi %r4, %r4, -1 104 addi %r3, %r3, -1 105 106 /* Copy remaining bytes */ 107.Lcopy_remaining: 108 mtctr %r7 109.Lcopy_remaining_loop: 110 lbzu %r6, 1(%r4) 111 stbu %r6, 1(%r3) 112 bdnz .Lcopy_remaining_loop 113 114.Lexit: 115 /* Restore dst */ 116 mr %r3, %r8 117 blr 118 119END(FN_NAME) 120 121 .section .note.GNU-stack,"",%progbits 122 123