Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
0003 
0004 #include <linux/linkage.h>
0005 #include "sysdep.h"
0006 
0007 ENTRY(__memcpy)
0008 ENTRY(memcpy)
0009     /* Test if len less than 4 bytes.  */
0010     mov r12, r0
0011     cmplti  r2, 4
0012     bt  .L_copy_by_byte
0013 
0014     andi    r13, r0, 3
0015     movi    r19, 4
0016     /* Test if dest is not 4 bytes aligned.  */
0017     bnez    r13, .L_dest_not_aligned
0018 
0019 /* Hardware can handle unaligned access directly.  */
0020 .L_dest_aligned:
0021     /* If dest is aligned, then copy.  */
0022     zext    r18, r2, 31, 4
0023 
0024     /* Test if len less than 16 bytes.  */
0025     bez r18, .L_len_less_16bytes
0026     movi    r19, 0
0027 
0028     LABLE_ALIGN
0029 .L_len_larger_16bytes:
0030 #if defined(__CK860__)
0031     ldw r3, (r1, 0)
0032     stw r3, (r0, 0)
0033     ldw r3, (r1, 4)
0034     stw r3, (r0, 4)
0035     ldw r3, (r1, 8)
0036     stw r3, (r0, 8)
0037     ldw r3, (r1, 12)
0038     addi    r1, 16
0039     stw r3, (r0, 12)
0040     addi    r0, 16
0041 #else
0042     ldw r20, (r1, 0)
0043     ldw r21, (r1, 4)
0044     ldw r22, (r1, 8)
0045     ldw r23, (r1, 12)
0046     stw r20, (r0, 0)
0047     stw r21, (r0, 4)
0048     stw r22, (r0, 8)
0049     stw r23, (r0, 12)
0050     PRE_BNEZAD (r18)
0051     addi    r1, 16
0052     addi    r0, 16
0053 #endif
0054     BNEZAD (r18, .L_len_larger_16bytes)
0055 
0056 .L_len_less_16bytes:
0057     zext    r18, r2, 3, 2
0058     bez r18, .L_copy_by_byte
0059 .L_len_less_16bytes_loop:
0060     ldw r3, (r1, 0)
0061     PRE_BNEZAD (r18)
0062     addi    r1, 4
0063     stw r3, (r0, 0)
0064     addi    r0, 4
0065     BNEZAD (r18, .L_len_less_16bytes_loop)
0066 
0067 /* Test if len less than 4 bytes.  */
0068 .L_copy_by_byte:
0069     zext    r18, r2, 1, 0
0070     bez r18, .L_return
0071 .L_copy_by_byte_loop:
0072     ldb r3, (r1, 0)
0073     PRE_BNEZAD (r18)
0074     addi    r1, 1
0075     stb r3, (r0, 0)
0076     addi    r0, 1
0077     BNEZAD (r18, .L_copy_by_byte_loop)
0078 
0079 .L_return:
0080     mov r0, r12
0081     rts
0082 
0083 /*
0084  * If dest is not aligned, just copying some bytes makes the
0085  * dest align.
0086  */
0087 .L_dest_not_aligned:
0088     sub r13, r19, r13
0089     sub r2, r13
0090 
0091 /* Makes the dest align.  */
0092 .L_dest_not_aligned_loop:
0093     ldb r3, (r1, 0)
0094     PRE_BNEZAD (r13)
0095     addi    r1, 1
0096     stb r3, (r0, 0)
0097     addi    r0, 1
0098     BNEZAD (r13, .L_dest_not_aligned_loop)
0099     cmplti  r2, 4
0100     bt  .L_copy_by_byte
0101 
0102     /* Check whether the src is aligned.  */
0103     jbr .L_dest_aligned
0104 ENDPROC(__memcpy)