2005-06-23 22:01:20 -07:00
/ *
* arch/ x t e n s a / l i b / m e m s e t . S
*
* ANSI C s t a n d a r d l i b r a r y f u n c t i o n m e m s e t
* ( Well, a l m o s t . . f i x u p c o d e m i g h t r e t u r n z e r o . )
*
* This f i l e i s s u b j e c t t o t h e t e r m s a n d c o n d i t i o n s o f t h e G N U G e n e r a l
* Public L i c e n s e . S e e t h e f i l e " C O P Y I N G " i n t h e m a i n d i r e c t o r y o f
* this a r c h i v e f o r m o r e d e t a i l s .
*
* Copyright ( C ) 2 0 0 2 T e n s i l i c a I n c .
* /
2008-11-06 06:40:46 -08:00
# include < v a r i a n t / c o r e . h >
2005-06-23 22:01:20 -07:00
/ *
* void * m e m s e t ( v o i d * d s t , i n t c , s i z e _ t l e n g t h )
*
* The a l g o r i t h m i s a s f o l l o w s :
* Create a w o r d w i t h c i n a l l b y t e p o s i t i o n s
* If t h e d e s t i n a t i o n i s a l i g n e d ,
* do 1 6 B c h u c k s w i t h a l o o p , a n d t h e n f i n i s h u p w i t h
* 8 B, 4 B , 2 B , a n d 1 B s t o r e s c o n d i t i o n a l o n t h e l e n g t h .
* If d e s t i n a t i o n i s u n a l i g n e d , a l i g n i t b y c o n d i t i o n a l l y
* setting 1 B a n d 2 B a n d t h e n g o t o a l i g n e d c a s e .
* This c o d e t r i e s t o u s e f a l l - t h r o u g h b r a n c h e s f o r t h e c o m m o n
* case o f a n a l i g n e d d e s t i n a t i o n ( e x c e p t f o r t h e b r a n c h e s t o
* the a l i g n m e n t l a b e l s ) .
* /
/* Load or store instructions that may cause exceptions use the EX macro. */
# define E X ( i n s n ,r e g 1 ,r e g 2 ,o f f s e t ,h a n d l e r ) \
9 : insn r e g 1 , r e g 2 , o f f s e t ; \
.section _ _ ex_ t a b l e , " a " ; \
.word 9 b, h a n d l e r ; \
.previous
.text
.align 4
.global memset
.type memset,@function
memset :
entry s p , 1 6 # m i n i m a l s t a c k f r a m e
# a2 / d s t , a3 / c , a4 / l e n g t h
extui a3 , a3 , 0 , 8 # m a s k t o j u s t 8 b i t s
slli a7 , a3 , 8 # d u p l i c a t e c h a r a c t e r i n a l l b y t e s o f w o r d
or a3 , a3 , a7 # . . .
slli a7 , a3 , 1 6 # . . .
or a3 , a3 , a7 # . . .
mov a5 , a2 # c o p y d s t s o t h a t a 2 i s r e t u r n v a l u e
movi a6 , 3 # f o r a l i g n m e n t t e s t s
bany a2 , a6 , . L d s t u n a l i g n e d # i f d s t i s u n a l i g n e d
.L0 : # return h e r e f r o m . L d s t u n a l i g n e d w h e n d s t i s a l i g n e d
srli a7 , a4 , 4 # n u m b e r o f l o o p i t e r a t i o n s w i t h 16 B
# per i t e r a t i o n
bnez a4 , . L a l i g n e d
retw
/ *
* Destination i s w o r d - a l i g n e d .
* /
# set 1 6 b y t e s p e r i t e r a t i o n f o r w o r d - a l i g n e d d s t
.align 4 # 1 mod 4 a l i g n m e n t f o r L O O P N E Z
.byte 0 # ( 0 mod 4 a l i g n m e n t f o r L B E G )
.Laligned :
# if X C H A L _ H A V E _ L O O P S
loopnez a7 , . L o o p1 d o n e
# else / * ! X C H A L _ H A V E _ L O O P S * /
beqz a7 , . L o o p1 d o n e
slli a6 , a7 , 4
add a6 , a6 , a5 # a 6 = e n d o f l a s t 1 6 B c h u n k
# endif / * ! X C H A L _ H A V E _ L O O P S * /
.Loop1 :
EX( s32 i , a3 , a5 , 0 , m e m s e t _ f i x u p )
EX( s32 i , a3 , a5 , 4 , m e m s e t _ f i x u p )
EX( s32 i , a3 , a5 , 8 , m e m s e t _ f i x u p )
EX( s32 i , a3 , a5 , 1 2 , m e m s e t _ f i x u p )
addi a5 , a5 , 1 6
# if ! X C H A L _ H A V E _ L O O P S
blt a5 , a6 , . L o o p1
# endif / * ! X C H A L _ H A V E _ L O O P S * /
.Loop1done :
bbci. l a4 , 3 , . L 2
# set 8 b y t e s
EX( s32 i , a3 , a5 , 0 , m e m s e t _ f i x u p )
EX( s32 i , a3 , a5 , 4 , m e m s e t _ f i x u p )
addi a5 , a5 , 8
.L2 :
bbci. l a4 , 2 , . L 3
# set 4 b y t e s
EX( s32 i , a3 , a5 , 0 , m e m s e t _ f i x u p )
addi a5 , a5 , 4
.L3 :
bbci. l a4 , 1 , . L 4
# set 2 b y t e s
EX( s16 i , a3 , a5 , 0 , m e m s e t _ f i x u p )
addi a5 , a5 , 2
.L4 :
bbci. l a4 , 0 , . L 5
# set 1 b y t e
EX( s8 i , a3 , a5 , 0 , m e m s e t _ f i x u p )
.L5 :
.Lret1 :
retw
/ *
* Destination i s u n a l i g n e d
* /
.Ldstunaligned :
bltui a4 , 8 , . L b y t e s e t # d o s h o r t c o p i e s b y t e b y b y t e
bbci. l a5 , 0 , . L 2 0 # b r a n c h i f d s t a l i g n m e n t h a l f - a l i g n e d
# dst i s o n l y b y t e a l i g n e d
# set 1 b y t e
EX( s8 i , a3 , a5 , 0 , m e m s e t _ f i x u p )
addi a5 , a5 , 1
addi a4 , a4 , - 1
# now r e t e s t i f d s t a l i g n e d
bbci. l a5 , 1 , . L 0 # i f n o w a l i g n e d , r e t u r n t o m a i n a l g o r i t h m
.L20 :
# dst h a l f - a l i g n e d
# set 2 b y t e s
EX( s16 i , a3 , a5 , 0 , m e m s e t _ f i x u p )
addi a5 , a5 , 2
addi a4 , a4 , - 2
j . L 0 # d s t i s n o w a l i g n e d , r e t u r n t o m a i n a l g o r i t h m
/ *
* Byte b y b y t e s e t
* /
.align 4
.byte 0 # 1 mod 4 a l i g n m e n t f o r L O O P N E Z
# ( 0 mod 4 a l i g n m e n t f o r L B E G )
.Lbyteset :
# if X C H A L _ H A V E _ L O O P S
loopnez a4 , . L b y t e s e t d o n e
# else / * ! X C H A L _ H A V E _ L O O P S * /
beqz a4 , . L b y t e s e t d o n e
add a6 , a5 , a4 # a 6 = e n d i n g a d d r e s s
# endif / * ! X C H A L _ H A V E _ L O O P S * /
.Lbyteloop :
EX( s8 i , a3 , a5 , 0 , m e m s e t _ f i x u p )
addi a5 , a5 , 1
# if ! X C H A L _ H A V E _ L O O P S
blt a5 , a6 , . L b y t e l o o p
# endif / * ! X C H A L _ H A V E _ L O O P S * /
.Lbytesetdone :
retw
.section .fixup , " ax"
.align 4
/* We return zero if a failure occurred. */
memset_fixup :
movi a2 , 0
retw