/* * Copyright (C) 2016-2017 Andes Technology, Inc. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ #include !========================================================== ! void *memcpy(void *dst, const void *src, int n); ! ! dst: $r0 ! src: $r1 ! n : $r2 ! ret: $r0 - pointer to the memory area dst. !========================================================== .weak memcpy ENTRY(memcpy) move $r5, $r0 beq $r0, $r1, .Lquit_memcpy beqz $r2, .Lquit_memcpy srli $r3, $r2, #5 ! check if len < cache-line size 32 beqz $r3, .Lword_copy_entry andi $r4, $r0, #0x3 ! check byte-align beqz $r4, .Lunalign_word_copy_entry addi $r4, $r4, #-4 abs $r4, $r4 ! check how many un-align byte to copy sub $r2, $r2, $r4 ! update $R2 .Lunalign_byte_copy: lbi.bi $r3, [$r1], #1 addi $r4, $r4, #-1 sbi.bi $r3, [$r0], #1 bnez $r4, .Lunalign_byte_copy beqz $r2, .Lquit_memcpy .Lunalign_word_copy_entry: andi $r3, $r0, 0x1f ! check cache-line unaligncount beqz $r3, .Lcache_copy addi $r3, $r3, #-32 abs $r3, $r3 sub $r2, $r2, $r3 ! update $R2 .Lunalign_word_copy: lmw.bim $r4, [$r1], $r4 addi $r3, $r3, #-4 smw.bim $r4, [$r0], $r4 bnez $r3, .Lunalign_word_copy beqz $r2, .Lquit_memcpy addi $r3, $r2, #-32 ! to check $r2 < cache_line, than go to .Lword_copy bltz $r3, .Lword_copy_entry .Lcache_copy: srli $r3, $r2, #5 beqz $r3, .Lword_copy_entry pushm $r6, $r13 cfi_adjust_cfa_offset(32) cfi_rel_offset(r6, 0) cfi_rel_offset(r7, 4) cfi_rel_offset(r8, 8) cfi_rel_offset(r9, 12) cfi_rel_offset(r10, 16) cfi_rel_offset(r11, 20) cfi_rel_offset(r12, 24) cfi_rel_offset(r13, 28) .L3: lmw.bim $r6, [$r1], $r13 addi $r3, $r3, #-1 smw.bim $r6, [$r0], $r13 bnez $r3, .L3 popm $r6, $r13 cfi_adjust_cfa_offset(-32) cfi_restore(r6) cfi_restore(r7) cfi_restore(r8) cfi_restore(r9) cfi_restore(r10) cfi_restore(r11) cfi_restore(r12) cfi_restore(r13) .Lword_copy_entry: andi $r2, $r2, #31 beqz $r2, .Lquit_memcpy srli $r3, $r2, #2 beqz $r3, .Lbyte_copy .Lword_copy: lmw.bim $r4, [$r1], $r4 addi $r3, $r3, #-1 smw.bim $r4, [$r0], $r4 bnez $r3, .Lword_copy andi $r2, $r2, #3 beqz $r2, .Lquit_memcpy .Lbyte_copy: lbi.bi $r3, [$r1], #1 addi $r2, $r2, #-1 sbi.bi $r3, [$r0], #1 bnez $r2, .Lbyte_copy .Lquit_memcpy: move $r0, $r5 ret END(memcpy) libc_hidden_def(memcpy)