2018-09-05 14:25:18 +08:00
/* SPDX-License-Identifier: GPL-2.0 */
/ / Copyright ( C ) 2 0 1 8 H a n g z h o u C - S K Y M i c r o s y s t e m s c o . ,l t d .
# include < l i n u x / l i n k a g e . h >
# include " s y s d e p . h "
ENTRY( _ _ m e m c p y )
ENTRY( m e m c p y )
/* Test if len less than 4 bytes. */
mov r12 , r0
cmplti r2 , 4
bt . L _ c o p y _ b y _ b y t e
andi r13 , r0 , 3
movi r19 , 4
/* Test if dest is not 4 bytes aligned. */
bnez r13 , . L _ d e s t _ n o t _ a l i g n e d
/* Hardware can handle unaligned access directly. */
.L_dest_aligned :
/* If dest is aligned, then copy. */
zext r18 , r2 , 3 1 , 4
/* Test if len less than 16 bytes. */
bez r18 , . L _ l e n _ l e s s _ 1 6 b y t e s
movi r19 , 0
LABLE_ A L I G N
.L_len_larger_16bytes :
2018-12-31 01:19:29 +08:00
# if d e f i n e d ( _ _ C K 8 6 0 _ _ )
2018-09-05 14:25:18 +08:00
ldw r3 , ( r1 , 0 )
stw r3 , ( r0 , 0 )
ldw r3 , ( r1 , 4 )
stw r3 , ( r0 , 4 )
ldw r3 , ( r1 , 8 )
stw r3 , ( r0 , 8 )
ldw r3 , ( r1 , 1 2 )
addi r1 , 1 6
stw r3 , ( r0 , 1 2 )
addi r0 , 1 6
# else
ldw r20 , ( r1 , 0 )
ldw r21 , ( r1 , 4 )
ldw r22 , ( r1 , 8 )
ldw r23 , ( r1 , 1 2 )
stw r20 , ( r0 , 0 )
stw r21 , ( r0 , 4 )
stw r22 , ( r0 , 8 )
stw r23 , ( r0 , 1 2 )
PRE_ B N E Z A D ( r18 )
addi r1 , 1 6
addi r0 , 1 6
# endif
BNEZAD ( r18 , . L _ l e n _ l a r g e r _ 1 6 b y t e s )
.L_len_less_16bytes :
zext r18 , r2 , 3 , 2
bez r18 , . L _ c o p y _ b y _ b y t e
.L_len_less_16bytes_loop :
ldw r3 , ( r1 , 0 )
PRE_ B N E Z A D ( r18 )
addi r1 , 4
stw r3 , ( r0 , 0 )
addi r0 , 4
BNEZAD ( r18 , . L _ l e n _ l e s s _ 1 6 b y t e s _ l o o p )
/* Test if len less than 4 bytes. */
.L_copy_by_byte :
zext r18 , r2 , 1 , 0
bez r18 , . L _ r e t u r n
.L_copy_by_byte_loop :
ldb r3 , ( r1 , 0 )
PRE_ B N E Z A D ( r18 )
addi r1 , 1
stb r3 , ( r0 , 0 )
addi r0 , 1
BNEZAD ( r18 , . L _ c o p y _ b y _ b y t e _ l o o p )
.L_return :
mov r0 , r12
rts
/ *
* If d e s t i s n o t a l i g n e d , j u s t c o p y i n g s o m e b y t e s m a k e s t h e
* dest a l i g n .
* /
.L_dest_not_aligned :
sub r13 , r19 , r13
sub r2 , r13
/* Makes the dest align. */
.L_dest_not_aligned_loop :
ldb r3 , ( r1 , 0 )
PRE_ B N E Z A D ( r13 )
addi r1 , 1
stb r3 , ( r0 , 0 )
addi r0 , 1
BNEZAD ( r13 , . L _ d e s t _ n o t _ a l i g n e d _ l o o p )
cmplti r2 , 4
bt . L _ c o p y _ b y _ b y t e
/* Check whether the src is aligned. */
jbr . L _ d e s t _ a l i g n e d
ENDPROC( _ _ m e m c p y )