Path: blob/main/lib/libc/powerpc64/string/memcpy.S
39530 views
/*-1* Copyright (c) 2018 Instituto de Pesquisas Eldorado2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. Neither the name of the author nor the names of its contributors may13* be used to endorse or promote products derived from this software14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*27*/2829#include <machine/asm.h>30#ifndef FN_NAME31#define FN_NAME __memcpy32WEAK_REFERENCE(__memcpy, memcpy);33#define BLOCK_BITS 434#endif3536#define BLOCK_BYTES (1 << BLOCK_BITS)37#define BLOCK_MASK (BLOCK_BYTES - 1)3839/* Minimum 8 byte alignment, to avoid cache-inhibited alignment faults. */40#ifndef ALIGN_MASK41#define ALIGN_MASK 0x742#endif4344/*45* r3: dst46* r4: src47* r5: len48*/49ENTRY(FN_NAME)50cmpdi %r5, 0 /* len == 0? nothing to do */51beqlr-5253/* If src and dst are relatively misaligned, do byte copies. */54andi. %r8, %r3, ALIGN_MASK55andi. %r7, %r4, ALIGN_MASK56cmpd %r8, %r757mr %r7, %r558mr %r8, %r3 /* save dst */59bne .Lcopy_remaining_fix_index_byte6061/* align src */62.Lalignment_loop:63lbz %r6, 0(%r4)64stb %r6, 0(%r3)65addi %r3, %r3, 166addi %r4, %r4, 167addi %r5, %r5, -168cmpdi %r5, 069beq .Lexit70andi. %r0, %r4, BLOCK_MASK71bne .Lalignment_loop7273/* r7 = remaining, non-block, bytes */74andi. %r7, %r5, BLOCK_MASK7576/* Check if there are blocks of BLOCK_BYTES to be copied */77xor. %r5, %r5, %r778beq .Lcopy_remaining_fix_index_byte7980#ifdef FN_COPY_LOOP81FN_COPY_LOOP82#else83/* Setup to copy word with ldu and stdu */84ld %r6, 0(%r4)85ld %r9, 8(%r4)86std %r6, 0(%r3)87std %r9, 8(%r3)88addi %r5, %r5, -BLOCK_BYTES89cmpd %r5, 090beq .Lcopy_remaining_fix_index_word9192srdi %r5, %r5, BLOCK_BITS93mtctr %r594.Lcopy_word:95ldu %r6, 16(%r4)96ld %r9, 8(%r4)97stdu %r6, 16(%r3)98std %r9, 8(%r3)99bdnz .Lcopy_word100101.Lcopy_remaining_fix_index_word:102/* Check if there are remaining bytes */103cmpd %r7, 0104beq .Lexit105addi %r3, %r3, BLOCK_MASK106addi %r4, %r4, BLOCK_MASK107b .Lcopy_remaining108#endif109110.Lcopy_remaining_fix_index_byte:111addi %r4, %r4, -1112addi %r3, %r3, -1113114/* Copy remaining bytes */115.Lcopy_remaining:116mtctr %r7117.Lcopy_remaining_loop:118lbzu %r6, 1(%r4)119stbu %r6, 1(%r3)120bdnz .Lcopy_remaining_loop121122.Lexit:123/* Restore dst */124mr %r3, %r8125blr126127END(FN_NAME)128129.section .note.GNU-stack,"",%progbits130131132133