2005-11-01 19:52:23 +00:00
/ *
* linux/ a r c h / a r m / l i b / m e m m o v e . S
*
* Author : Nicolas P i t r e
* Created : Sep 2 8 , 2 0 0 5
* Copyright : ( C) M o n t a V i s t a S o f t w a r e I n c .
*
* 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
/ *
* Prototype : void * m e m m o v e ( v o i d * d e s t , c o n s t v o i d * s r c , s i z e _ t n ) ;
*
* Note :
*
* If t h e m e m o r y r e g i o n s d o n ' t o v e r l a p , w e s i m p l y b r a n c h t o m e m c p y w h i c h i s
* normally a b i t f a s t e r . O t h e r w i s e t h e c o p y i s d o n e g o i n g d o w n w a r d s . T h i s
* is a t r a n s p o s i t i o n o f t h e c o d e f r o m c o p y _ t e m p l a t e . S b u t w i t h t h e c o p y
* occurring i n t h e o p p o s i t e d i r e c t i o n .
* /
ENTRY( m e m m o v e )
subs i p , r0 , r1
cmphi r2 , i p
bls m e m c p y
stmfd s p ! , { r0 , r4 , l r }
add r1 , r1 , r2
add r0 , r0 , r2
subs r2 , r2 , #4
blt 8 f
ands i p , r0 , #3
PLD( p l d [ r1 , #- 4 ] )
bne 9 f
ands i p , r1 , #3
bne 1 0 f
1 : subs r2 , r2 , #( 28 )
stmfd s p ! , { r5 - r8 }
blt 5 f
2008-03-31 12:38:31 -04:00
CALGN( a n d s i p , r0 , #31 )
2005-11-01 19:52:23 +00:00
CALGN( s b c n e s r4 , i p , r2 ) @ C is always set here
CALGN( b c s 2 f )
CALGN( a d r r4 , 6 f )
CALGN( s u b s r2 , r2 , i p ) @ C is set here
2008-06-11 12:40:13 -04:00
CALGN( r s b i p , i p , #32 )
2005-11-01 19:52:23 +00:00
CALGN( a d d p c , r4 , i p )
PLD( p l d [ r1 , #- 4 ] )
2 : PLD( s u b s r2 , r2 , #96 )
PLD( p l d [ r1 , #- 32 ] )
PLD( b l t 4 f )
PLD( p l d [ r1 , #- 64 ] )
PLD( p l d [ r1 , #- 96 ] )
3 : PLD( p l d [ r1 , #- 128 ] )
4 : ldmdb r1 ! , { r3 , r4 , r5 , r6 , r7 , r8 , i p , l r }
subs r2 , r2 , #32
stmdb r0 ! , { r3 , r4 , r5 , r6 , r7 , r8 , i p , l r }
bge 3 b
PLD( c m n r2 , #96 )
PLD( b g e 4 b )
5 : ands i p , r2 , #28
rsb i p , i p , #32
addne p c , p c , i p @ C is always clear here
b 7 f
2010-03-29 10:29:46 +01:00
6 : W( n o p )
2009-07-24 12:32:57 +01:00
W( l d r ) r3 , [ r1 , #- 4 ] !
W( l d r ) r4 , [ r1 , #- 4 ] !
W( l d r ) r5 , [ r1 , #- 4 ] !
W( l d r ) r6 , [ r1 , #- 4 ] !
W( l d r ) r7 , [ r1 , #- 4 ] !
W( l d r ) r8 , [ r1 , #- 4 ] !
W( l d r ) l r , [ r1 , #- 4 ] !
2005-11-01 19:52:23 +00:00
add p c , p c , i p
nop
2010-03-29 10:29:46 +01:00
W( n o p )
2009-07-24 12:32:57 +01:00
W( s t r ) r3 , [ r0 , #- 4 ] !
W( s t r ) r4 , [ r0 , #- 4 ] !
W( s t r ) r5 , [ r0 , #- 4 ] !
W( s t r ) r6 , [ r0 , #- 4 ] !
W( s t r ) r7 , [ r0 , #- 4 ] !
W( s t r ) r8 , [ r0 , #- 4 ] !
W( s t r ) l r , [ r0 , #- 4 ] !
2005-11-01 19:52:23 +00:00
CALGN( b c s 2 b )
7 : ldmfd s p ! , { r5 - r8 }
8 : movs r2 , r2 , l s l #31
ldrneb r3 , [ r1 , #- 1 ] !
ldrcsb r4 , [ r1 , #- 1 ] !
ldrcsb i p , [ r1 , #- 1 ]
strneb r3 , [ r0 , #- 1 ] !
strcsb r4 , [ r0 , #- 1 ] !
strcsb i p , [ r0 , #- 1 ]
ldmfd s p ! , { r0 , r4 , p c }
9 : cmp i p , #2
ldrgtb r3 , [ r1 , #- 1 ] !
ldrgeb r4 , [ r1 , #- 1 ] !
ldrb l r , [ r1 , #- 1 ] !
strgtb r3 , [ r0 , #- 1 ] !
strgeb r4 , [ r0 , #- 1 ] !
subs r2 , r2 , i p
strb l r , [ r0 , #- 1 ] !
blt 8 b
ands i p , r1 , #3
beq 1 b
10 : bic r1 , r1 , #3
cmp i p , #2
ldr r3 , [ r1 , #0 ]
beq 1 7 f
blt 1 8 f
.macro backward_copy_shift push p u l l
subs r2 , r2 , #28
blt 1 4 f
2008-03-31 12:38:31 -04:00
CALGN( a n d s i p , r0 , #31 )
2005-11-01 19:52:23 +00:00
CALGN( s b c n e s r4 , i p , r2 ) @ C is always set here
CALGN( s u b c c r2 , r2 , i p )
CALGN( b c c 1 5 f )
11 : stmfd s p ! , { r5 - r9 }
PLD( p l d [ r1 , #- 4 ] )
PLD( s u b s r2 , r2 , #96 )
PLD( p l d [ r1 , #- 32 ] )
PLD( b l t 1 3 f )
PLD( p l d [ r1 , #- 64 ] )
PLD( p l d [ r1 , #- 96 ] )
12 : PLD( p l d [ r1 , #- 128 ] )
13 : ldmdb r1 ! , { r7 , r8 , r9 , i p }
mov l r , r3 , p u s h #\ p u s h
subs r2 , r2 , #32
ldmdb r1 ! , { r3 , r4 , r5 , r6 }
orr l r , l r , i p , p u l l #\ p u l l
mov i p , i p , p u s h #\ p u s h
orr i p , i p , r9 , p u l l #\ p u l l
mov r9 , r9 , p u s h #\ p u s h
orr r9 , r9 , r8 , p u l l #\ p u l l
mov r8 , r8 , p u s h #\ p u s h
orr r8 , r8 , r7 , p u l l #\ p u l l
mov r7 , r7 , p u s h #\ p u s h
orr r7 , r7 , r6 , p u l l #\ p u l l
mov r6 , r6 , p u s h #\ p u s h
orr r6 , r6 , r5 , p u l l #\ p u l l
mov r5 , r5 , p u s h #\ p u s h
orr r5 , r5 , r4 , p u l l #\ p u l l
mov r4 , r4 , p u s h #\ p u s h
orr r4 , r4 , r3 , p u l l #\ p u l l
stmdb r0 ! , { r4 - r9 , i p , l r }
bge 1 2 b
PLD( c m n r2 , #96 )
PLD( b g e 1 3 b )
ldmfd s p ! , { r5 - r9 }
14 : ands i p , r2 , #28
beq 1 6 f
15 : mov l r , r3 , p u s h #\ p u s h
ldr r3 , [ r1 , #- 4 ] !
subs i p , i p , #4
orr l r , l r , r3 , p u l l #\ p u l l
str l r , [ r0 , #- 4 ] !
bgt 1 5 b
CALGN( c m p r2 , #0 )
CALGN( b g e 1 1 b )
16 : add r1 , r1 , #( \ p u l l / 8 )
b 8 b
.endm
backward_ c o p y _ s h i f t p u s h =8 p u l l =24
17 : backward_ c o p y _ s h i f t p u s h =16 p u l l =16
18 : backward_ c o p y _ s h i f t p u s h =24 p u l l =8
2008-08-28 11:22:32 +01:00
ENDPROC( m e m m o v e )