2005-11-01 19:52:23 +00:00
/ *
* linux/ a r c h / a r m / l i b / c o p y _ t e m p l a t e . s
*
* Code t e m p l a t e f o r o p t i m i z e d m e m o r y c o p y f u n c t i o n s
*
* Author : Nicolas P i t r e
* Created : Sep 2 8 , 2 0 0 5
* Copyright : MontaVista 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 .
* /
/ *
* Theory o f o p e r a t i o n
* - - - - - - - - - - - - - - - - - - -
*
* This f i l e p r o v i d e s t h e c o r e c o d e f o r a f o r w a r d m e m o r y c o p y u s e d i n
* the i m p l e m e n t a t i o n o f m e m c o p y ( ) , c o p y _ t o _ u s e r ( ) a n d c o p y _ f r o m _ u s e r ( ) .
*
* The i n c l u d i n g f i l e m u s t d e f i n e t h e f o l l o w i n g a c c e s s o r m a c r o s
* according t o t h e n e e d o f t h e g i v e n f u n c t i o n :
*
* ldr1 w p t r r e g a b o r t
*
* This l o a d s o n e w o r d f r o m ' p t r ' , s t o r e s i t i n ' r e g ' a n d i n c r e m e n t s
* ' ptr' t o t h e n e x t w o r d . T h e ' a b o r t ' a r g u m e n t i s u s e d f o r f i x u p t a b l e s .
*
* ldr4 w p t r r e g 1 r e g 2 r e g 3 r e g 4 a b o r t
* ldr8 w p t r , r e g 1 r e g 2 r e g 3 r e g 4 r e g 5 r e g 6 r e g 7 r e g 8 a b o r t
*
* This l o a d s f o u r o r e i g h t w o r d s s t a r t i n g f r o m ' p t r ' , s t o r e s t h e m
* in p r o v i d e d r e g i s t e r s a n d i n c r e m e n t s ' p t r ' p a s t t h o s e w o r d s .
* The' a b o r t ' a r g u m e n t i s u s e d f o r f i x u p t a b l e s .
*
* ldr1 b p t r r e g c o n d a b o r t
*
* Similar t o l d r1 w , b u t i t l o a d s a b y t e a n d i n c r e m e n t s ' p t r ' o n e b y t e .
* It a l s o m u s t a p p l y t h e c o n d i t i o n c o d e i f p r o v i d e d , o t h e r w i s e t h e
* " al" c o n d i t i o n i s a s s u m e d b y d e f a u l t .
*
* str1 w p t r r e g a b o r t
* str8 w p t r r e g 1 r e g 2 r e g 3 r e g 4 r e g 5 r e g 6 r e g 7 r e g 8 a b o r t
* str1 b p t r r e g c o n d a b o r t
*
* Same a s t h e i r l d r * c o u n t e r p a r t s , b u t d a t a i s s t o r e d t o ' p t r ' l o c a t i o n
* rather t h a n b e i n g l o a d e d .
*
* enter r e g 1 r e g 2
*
* Preserve t h e p r o v i d e d r e g i s t e r s o n t h e s t a c k p l u s a n y a d d i t i o n a l
* data a s n e e d e d b y t h e i m p l e m e n t a t i o n i n c l u d i n g t h i s c o d e . C a l l e d
* upon c o d e e n t r y .
*
2014-11-26 14:38:33 +01:00
* usave r e g 1 r e g 2
*
* Unwind a n n o t a t i o n m a c r o i s c o r r e s p o n d i n g f o r ' e n t e r ' m a c r o .
* It t e l l u n w i n d e r t h a t p r e s e r v e d s o m e p r o v i d e d r e g i s t e r s o n t h e s t a c k
* and a d d i t i o n a l d a t a b y a p r i o r ' e n t e r ' m a c r o .
*
2005-11-01 19:52:23 +00:00
* exit r e g 1 r e g 2
*
* Restore r e g i s t e r s w i t h t h e v a l u e s p r e v i o u s l y s a v e d w i t h t h e
* ' preserv' m a c r o . C a l l e d u p o n c o d e t e r m i n a t i o n .
2009-07-24 12:32:57 +01:00
*
* LDR1 W _ S H I F T
* STR1 W _ S H I F T
*
* Correction t o b e a p p l i e d t o t h e " i p " r e g i s t e r w h e n b r a n c h i n g i n t o
* the l d r1 w o r s t r1 w i n s t r u c t i o n s ( s o m e o f t h e s e m a c r o s m a y e x p a n d t o
* than o n e 3 2 b i t i n s t r u c t i o n i n T h u m b - 2 )
2005-11-01 19:52:23 +00:00
* /
2014-11-26 14:38:33 +01:00
UNWIND( . f n s t a r t )
2005-11-01 19:52:23 +00:00
enter r4 , l r
2014-11-26 14:38:33 +01:00
UNWIND( . f n e n d )
UNWIND( . f n s t a r t )
usave r4 , l r @ in first stmdb block
2005-11-01 19:52:23 +00:00
subs r2 , r2 , #4
blt 8 f
ands i p , r0 , #3
PLD( p l d [ r1 , #0 ] )
bne 9 f
ands i p , r1 , #3
bne 1 0 f
1 : subs r2 , r2 , #( 28 )
stmfd s p ! , { r5 - r8 }
2014-11-26 14:38:33 +01:00
UNWIND( . f n e n d )
UNWIND( . f n s t a r t )
usave r4 , l r
UNWIND( . s a v e { r5 - r8 } ) @ in second stmfd block
2005-11-01 19:52:23 +00:00
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( r s b r3 , i p , #32 )
CALGN( s b c n e s r4 , r3 , 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 , r3 ) @ C gets set
CALGN( a d d p c , r4 , i p )
PLD( p l d [ r1 , #0 ] )
2 : PLD( s u b s r2 , r2 , #96 )
PLD( p l d [ r1 , #28 ] )
PLD( b l t 4 f )
PLD( p l d [ r1 , #60 ] )
PLD( p l d [ r1 , #92 ] )
3 : PLD( p l d [ r1 , #124 ] )
4 : ldr8 w r1 , r3 , r4 , r5 , r6 , r7 , r8 , i p , l r , a b o r t =20f
subs r2 , r2 , #32
str8 w r0 , r3 , r4 , r5 , r6 , r7 , r8 , i p , l r , a b o r t =20f
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
2009-07-24 12:32:57 +01:00
# if L D R 1 W _ S H I F T > 0
lsl i p , i p , #L D R 1 W _ S H I F T
# endif
2005-11-01 19:52:23 +00:00
addne p c , p c , i p @ C is always clear here
b 7 f
2009-07-24 12:32:57 +01:00
6 :
.rept ( 1 < < LDR1 W _ S H I F T )
W( n o p )
.endr
2005-11-01 19:52:23 +00:00
ldr1 w r1 , r3 , a b o r t =20f
ldr1 w r1 , r4 , a b o r t =20f
ldr1 w r1 , r5 , a b o r t =20f
ldr1 w r1 , r6 , a b o r t =20f
ldr1 w r1 , r7 , a b o r t =20f
ldr1 w r1 , r8 , a b o r t =20f
ldr1 w r1 , l r , a b o r t =20f
2009-07-24 12:32:57 +01:00
# if L D R 1 W _ S H I F T < S T R 1 W _ S H I F T
lsl i p , i p , #S T R 1 W _ S H I F T - L D R 1 W _ S H I F T
# elif L D R 1 W _ S H I F T > S T R 1 W _ S H I F T
lsr i p , i p , #L D R 1 W _ S H I F T - S T R 1 W _ S H I F T
# endif
2005-11-01 19:52:23 +00:00
add p c , p c , i p
nop
2009-07-24 12:32:57 +01:00
.rept ( 1 < < STR1 W _ S H I F T )
W( n o p )
.endr
2005-11-01 19:52:23 +00:00
str1 w r0 , r3 , a b o r t =20f
str1 w r0 , r4 , a b o r t =20f
str1 w r0 , r5 , a b o r t =20f
str1 w r0 , r6 , a b o r t =20f
str1 w r0 , r7 , a b o r t =20f
str1 w r0 , r8 , a b o r t =20f
str1 w r0 , l r , a b o r t =20f
CALGN( b c s 2 b )
7 : ldmfd s p ! , { r5 - r8 }
2014-11-26 14:38:33 +01:00
UNWIND( . f n e n d ) @ end of second stmfd block
2005-11-01 19:52:23 +00:00
2014-11-26 14:38:33 +01:00
UNWIND( . f n s t a r t )
usave r4 , l r @ still in first stmdb block
2005-11-01 19:52:23 +00:00
8 : movs r2 , r2 , l s l #31
ldr1 b r1 , r3 , n e , a b o r t =21f
ldr1 b r1 , r4 , c s , a b o r t =21f
ldr1 b r1 , i p , c s , a b o r t =21f
str1 b r0 , r3 , n e , a b o r t =21f
str1 b r0 , r4 , c s , a b o r t =21f
str1 b r0 , i p , c s , a b o r t =21f
exit r4 , p c
9 : rsb i p , i p , #4
cmp i p , #2
ldr1 b r1 , r3 , g t , a b o r t =21f
ldr1 b r1 , r4 , g e , a b o r t =21f
ldr1 b r1 , l r , a b o r t =21f
str1 b r0 , r3 , g t , a b o r t =21f
str1 b r0 , r4 , g e , a b o r t =21f
subs r2 , r2 , i p
str1 b r0 , l r , a b o r t =21f
blt 8 b
ands i p , r1 , #3
beq 1 b
10 : bic r1 , r1 , #3
cmp i p , #2
ldr1 w r1 , l r , a b o r t =21f
beq 1 7 f
bgt 1 8 f
2014-11-26 14:38:33 +01:00
UNWIND( . f n e n d )
2005-11-01 19:52:23 +00:00
.macro forward_copy_shift pull p u s h
2014-11-26 14:38:33 +01:00
UNWIND( . f n s t a r t )
usave r4 , l r @ still in first stmdb block
2005-11-01 19:52:23 +00:00
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( r s b i p , i p , #32 )
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 }
2014-11-26 14:38:33 +01:00
UNWIND( . f n e n d )
2005-11-01 19:52:23 +00:00
2014-11-26 14:38:33 +01:00
UNWIND( . f n s t a r t )
usave r4 , l r
UNWIND( . s a v e { r5 - r9 } ) @ in new second stmfd block
2005-11-01 19:52:23 +00:00
PLD( p l d [ r1 , #0 ] )
PLD( s u b s r2 , r2 , #96 )
PLD( p l d [ r1 , #28 ] )
PLD( b l t 1 3 f )
PLD( p l d [ r1 , #60 ] )
PLD( p l d [ r1 , #92 ] )
12 : PLD( p l d [ r1 , #124 ] )
13 : ldr4 w r1 , r4 , r5 , r6 , r7 , a b o r t =19f
2014-02-25 08:41:09 +01:00
mov r3 , l r , l s p u l l #\ p u l l
2005-11-01 19:52:23 +00:00
subs r2 , r2 , #32
ldr4 w r1 , r8 , r9 , i p , l r , a b o r t =19f
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r4 , l s p u s h #\ p u s h
mov r4 , r4 , l s p u l l #\ p u l l
orr r4 , r4 , r5 , l s p u s h #\ p u s h
mov r5 , r5 , l s p u l l #\ p u l l
orr r5 , r5 , r6 , l s p u s h #\ p u s h
mov r6 , r6 , l s p u l l #\ p u l l
orr r6 , r6 , r7 , l s p u s h #\ p u s h
mov r7 , r7 , l s p u l l #\ p u l l
orr r7 , r7 , r8 , l s p u s h #\ p u s h
mov r8 , r8 , l s p u l l #\ p u l l
orr r8 , r8 , r9 , l s p u s h #\ p u s h
mov r9 , r9 , l s p u l l #\ p u l l
orr r9 , r9 , i p , l s p u s h #\ p u s h
mov i p , i p , l s p u l l #\ p u l l
orr i p , i p , l r , l s p u s h #\ p u s h
ARM: 8827/1: fix argument count to match macro definition
The macro str8w takes 10 arguments, abort being the 10th. In this
particular instantiation the abort argument is passed as 11th
argument leading to an error when using LLVM's integrated
assembler:
<instantiation>:46:47: error: too many positional arguments
str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
^
arch/arm/lib/copy_template.S:277:5: note: while in macro instantiation
18: forward_copy_shift pull=24 push=8
^
The argument is not used in the macro hence this does not change
code generation.
Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
2019-01-24 21:41:59 +01:00
str8 w r0 , r3 , r4 , r5 , r6 , r7 , r8 , r9 , i p , a b o r t =19f
2005-11-01 19:52:23 +00:00
bge 1 2 b
PLD( c m n r2 , #96 )
PLD( b g e 1 3 b )
ldmfd s p ! , { r5 - r9 }
2014-11-26 14:38:33 +01:00
UNWIND( . f n e n d ) @ end of the second stmfd block
2005-11-01 19:52:23 +00:00
2014-11-26 14:38:33 +01:00
UNWIND( . f n s t a r t )
usave r4 , l r @ still in first stmdb block
2005-11-01 19:52:23 +00:00
14 : ands i p , r2 , #28
beq 1 6 f
2014-02-25 08:41:09 +01:00
15 : mov r3 , l r , l s p u l l #\ p u l l
2005-11-01 19:52:23 +00:00
ldr1 w r1 , l r , a b o r t =21f
subs i p , i p , #4
2014-02-25 08:41:09 +01:00
orr r3 , r3 , l r , l s p u s h #\ p u s h
2005-11-01 19:52:23 +00:00
str1 w r0 , r3 , a b o r t =21f
bgt 1 5 b
CALGN( c m p r2 , #0 )
CALGN( b g e 1 1 b )
16 : sub r1 , r1 , #( \ p u s h / 8 )
b 8 b
2014-11-26 14:38:33 +01:00
UNWIND( . f n e n d )
2005-11-01 19:52:23 +00:00
.endm
forward_ c o p y _ s h i f t p u l l =8 p u s h =24
17 : forward_ c o p y _ s h i f t p u l l =16 p u s h =16
18 : forward_ c o p y _ s h i f t p u l l =24 p u s h =8
/ *
2006-03-28 01:56:53 -08:00
* Abort p r e a m b l e a n d c o m p l e t i o n m a c r o s .
2005-11-01 19:52:23 +00:00
* If a f i x u p h a n d l e r i s r e q u i r e d t h e n t h o s e m a c r o s m u s t s u r r o u n d i t .
* It i s a s s u m e d t h a t t h e f i x u p c o d e w i l l h a n d l e t h e p r i v a t e p a r t o f
* the e x i t m a c r o .
* /
.macro copy_abort_preamble
19 : ldmfd s p ! , { r5 - r9 }
b 2 1 f
20 : ldmfd s p ! , { r5 - r8 }
21 :
.endm
.macro copy_abort_end
ldmfd s p ! , { r4 , p c }
.endm