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 "
.weak memmove
ENTRY( _ _ m e m m o v e )
ENTRY( m e m m o v e )
subu r3 , r0 , r1
cmphs r3 , r2
bt m e m c p y
mov r12 , r0
addu r0 , r0 , r2
addu r1 , r1 , r2
/* Test if len less than 4 bytes. */
cmplti r2 , 4
bt . L _ c o p y _ b y _ b y t e
andi r13 , r0 , 3
/* 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
/* len > 16 bytes */
LABLE_ A L I G N
.L_len_larger_16bytes :
subi r1 , 1 6
subi r0 , 1 6
2019-02-19 12:32:41 +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 , 1 2 )
stw r3 , ( r0 , 1 2 )
ldw r3 , ( r1 , 8 )
stw r3 , ( r0 , 8 )
ldw r3 , ( r1 , 4 )
stw r3 , ( r0 , 4 )
ldw r3 , ( r1 , 0 )
stw r3 , ( r0 , 0 )
# 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 )
# 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 :
subi r1 , 4
subi r0 , 4
ldw r3 , ( r1 , 0 )
PRE_ B N E Z A D ( r18 )
stw r3 , ( r0 , 0 )
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 :
subi r1 , 1
subi r0 , 1
ldb r3 , ( r1 , 0 )
PRE_ B N E Z A D ( r18 )
stb r3 , ( r0 , 0 )
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 s o m e b y t e s m a k e s t h e d e s t
align. * /
.L_dest_not_aligned :
sub r2 , r13
.L_dest_not_aligned_loop :
subi r1 , 1
subi r0 , 1
/* Makes the dest align. */
ldb r3 , ( r1 , 0 )
PRE_ B N E Z A D ( r13 )
stb r3 , ( r0 , 0 )
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 m o v e )
ENDPROC( _ _ m e m m o v e )