^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include "sysdep.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) ENTRY(__memcpy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) ENTRY(memcpy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /* Test if len less than 4 bytes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) mov r12, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) cmplti r2, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) bt .L_copy_by_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) andi r13, r0, 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) movi r19, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* Test if dest is not 4 bytes aligned. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) bnez r13, .L_dest_not_aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* Hardware can handle unaligned access directly. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) .L_dest_aligned:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* If dest is aligned, then copy. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) zext r18, r2, 31, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* Test if len less than 16 bytes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) bez r18, .L_len_less_16bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) movi r19, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) LABLE_ALIGN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .L_len_larger_16bytes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #if defined(__CK860__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) ldw r3, (r1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) stw r3, (r0, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ldw r3, (r1, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) stw r3, (r0, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) ldw r3, (r1, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) stw r3, (r0, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) ldw r3, (r1, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) addi r1, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) stw r3, (r0, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) addi r0, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ldw r20, (r1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) ldw r21, (r1, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ldw r22, (r1, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ldw r23, (r1, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) stw r20, (r0, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) stw r21, (r0, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) stw r22, (r0, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) stw r23, (r0, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) PRE_BNEZAD (r18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) addi r1, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) addi r0, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) BNEZAD (r18, .L_len_larger_16bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .L_len_less_16bytes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) zext r18, r2, 3, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) bez r18, .L_copy_by_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .L_len_less_16bytes_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ldw r3, (r1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) PRE_BNEZAD (r18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) addi r1, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) stw r3, (r0, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) addi r0, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) BNEZAD (r18, .L_len_less_16bytes_loop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Test if len less than 4 bytes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .L_copy_by_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) zext r18, r2, 1, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bez r18, .L_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .L_copy_by_byte_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ldb r3, (r1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) PRE_BNEZAD (r18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) addi r1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) stb r3, (r0, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) addi r0, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) BNEZAD (r18, .L_copy_by_byte_loop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .L_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) mov r0, r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * If dest is not aligned, just copying some bytes makes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * dest align.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .L_dest_not_aligned:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) sub r13, r19, r13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) sub r2, r13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* Makes the dest align. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .L_dest_not_aligned_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ldb r3, (r1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) PRE_BNEZAD (r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) addi r1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) stb r3, (r0, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) addi r0, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) BNEZAD (r13, .L_dest_not_aligned_loop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) cmplti r2, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) bt .L_copy_by_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Check whether the src is aligned. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) jbr .L_dest_aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ENDPROC(__memcpy)