2005-04-17 02:20:36 +04:00
/ *
* linux/ a r c h / a r m / l i b / m e m z e r o . S
*
* Copyright ( C ) 1 9 9 5 - 2 0 0 0 R u s s e l l K i n g
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or modify
* it u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e v e r s i o n 2 a s
* published b y t h e F r e e S o f t w a r e F o u n d a t i o n .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s s e m b l e r . h >
.text
.align 5
.word 0
/ *
* Align t h e p o i n t e r i n r0 . r3 c o n t a i n s t h e n u m b e r o f b y t e s t h a t w e a r e
* mis- a l i g n e d b y , a n d r1 i s t h e n u m b e r o f b y t e s . I f r1 < 4 , t h e n w e
* don' t b o t h e r ; we use byte stores instead.
* /
1 : subs r1 , r1 , #4 @ 1 do we have enough
blt 5 f @ 1 bytes to align with?
cmp r3 , #2 @ 1
strltb r2 , [ r0 ] , #1 @ 1
strleb r2 , [ r0 ] , #1 @ 1
strb r2 , [ r0 ] , #1 @ 1
add r1 , r1 , r3 @ 1 (r1 = r1 - (4 - r3))
/ *
* The p o i n t e r i s n o w a l i g n e d a n d t h e l e n g t h i s a d j u s t e d . T r y d o i n g t h e
* memzero a g a i n .
* /
ENTRY( _ _ m e m z e r o )
mov r2 , #0 @ 1
ands r3 , r0 , #3 @ 1 unaligned?
bne 1 b @ 1
/ *
* r3 = 0 , a n d w e k n o w t h a t t h e p o i n t e r i n r0 i s a l i g n e d t o a w o r d b o u n d a r y .
* /
cmp r1 , #16 @ 1 we can skip this chunk if we
blt 4 f @ 1 have < 16 bytes
2008-04-12 05:04:28 +04:00
# if ! C A L G N ( 1 ) + 0
2005-04-17 02:20:36 +04:00
/ *
* We n e e d a n e x t r a r e g i s t e r f o r t h i s l o o p - s a v e t h e r e t u r n a d d r e s s a n d
* use t h e L R
* /
str l r , [ s p , #- 4 ] ! @ 1
mov i p , r2 @ 1
mov l r , r2 @ 1
3 : subs r1 , r1 , #64 @ 1 write 32 bytes out per loop
stmgeia r0 ! , { r2 , r3 , i p , l r } @ 4
stmgeia r0 ! , { r2 , r3 , i p , l r } @ 4
stmgeia r0 ! , { r2 , r3 , i p , l r } @ 4
stmgeia r0 ! , { r2 , r3 , i p , l r } @ 4
bgt 3 b @ 1
2006-06-25 14:23:45 +04:00
ldmeqfd s p ! , { p c } @ 1/2 quick exit
2005-04-17 02:20:36 +04:00
/ *
* No n e e d t o c o r r e c t t h e c o u n t ; we're only testing bits from now on
* /
tst r1 , #32 @ 1
stmneia r0 ! , { r2 , r3 , i p , l r } @ 4
stmneia r0 ! , { r2 , r3 , i p , l r } @ 4
tst r1 , #16 @ 1 16 bytes or more?
stmneia r0 ! , { r2 , r3 , i p , l r } @ 4
ldr l r , [ s p ] , #4 @ 1
2008-04-12 05:04:28 +04:00
# else
/ *
* This v e r s i o n a l i g n s t h e d e s t i n a t i o n p o i n t e r i n o r d e r t o w r i t e
* whole c a c h e l i n e s a t o n c e .
* /
stmfd s p ! , { r4 - r7 , l r }
mov r4 , r2
mov r5 , r2
mov r6 , r2
mov r7 , r2
mov i p , r2
mov l r , r2
cmp r1 , #96
andgts i p , r0 , #31
ble 3 f
rsb i p , i p , #32
sub r1 , r1 , i p
movs i p , i p , l s l #( 32 - 4 )
stmcsia r0 ! , { r4 , r5 , r6 , r7 }
stmmiia r0 ! , { r4 , r5 }
movs i p , i p , l s l #2
strcs r2 , [ r0 ] , #4
3 : subs r1 , r1 , #64
stmgeia r0 ! , { r2 - r7 , i p , l r }
stmgeia r0 ! , { r2 - r7 , i p , l r }
bgt 3 b
ldmeqfd s p ! , { r4 - r7 , p c }
tst r1 , #32
stmneia r0 ! , { r2 - r7 , i p , l r }
tst r1 , #16
stmneia r0 ! , { r4 - r7 }
ldmfd s p ! , { r4 - r7 , l r }
# endif
2005-04-17 02:20:36 +04:00
4 : tst r1 , #8 @ 1 8 bytes or more?
stmneia r0 ! , { r2 , r3 } @ 2
tst r1 , #4 @ 1 4 bytes or more?
strne r2 , [ r0 ] , #4 @ 1
/ *
* When w e g e t h e r e , w e ' v e g o t l e s s t h a n 4 b y t e s t o z e r o . W e
* may h a v e a n u n a l i g n e d p o i n t e r a s w e l l .
* /
5 : tst r1 , #2 @ 1 2 bytes or more?
strneb r2 , [ r0 ] , #1 @ 1
strneb r2 , [ r0 ] , #1 @ 1
tst r1 , #1 @ 1 a byte left over
strneb r2 , [ r0 ] , #1 @ 1
2006-06-25 14:17:23 +04:00
mov p c , l r @ 1
2008-08-28 14:22:32 +04:00
ENDPROC( _ _ m e m z e r o )