2005-04-16 15:20:36 -07:00
/ * atomic- o p s . S : k e r n e l a t o m i c o p e r a t i o n s
*
* For a n e x p l a n a t i o n o f h o w a t o m i c o p s w o r k i n t h i s a r c h , s e e :
2008-02-03 15:54:28 +02:00
* Documentation/ f r v / a t o m i c - o p s . t x t
2005-04-16 15:20:36 -07:00
*
* Copyright ( C ) 2 0 0 4 R e d H a t , I n c . A l l R i g h t s R e s e r v e d .
* Written b y D a v i d H o w e l l s ( d h o w e l l s @redhat.com)
*
* 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 i t 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
* as p u b l i s h e d 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 ; either version
* 2 of t h e L i c e n s e , o r ( a t y o u r o p t i o n ) a n y l a t e r v e r s i o n .
* /
# include < a s m / s p r - r e g s . h >
.text
.balign 4
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# unsigned l o n g a t o m i c _ t e s t _ a n d _ A N D N O T _ m a s k ( u n s i g n e d l o n g m a s k , v o l a t i l e u n s i g n e d l o n g * v ) ;
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
.globl atomic_test_and_ANDNOT_mask
.type atomic_ t e s t _ a n d _ A N D N O T _ m a s k ,@function
atomic_test_and_ANDNOT_mask :
not. p g r8 ,g r10
0 :
orcc g r0 ,g r0 ,g r0 ,i c c3 / * s e t I C C 3 . Z * /
ckeq i c c3 ,c c7
ld. p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
orcr c c7 ,c c7 ,c c3 / * s e t C C 3 t o t r u e * /
and g r8 ,g r10 ,g r11
cst. p g r11 ,@(gr9,gr0) ,cc3,#1
corcc g r29 ,g r29 ,g r0 ,c c3 ,#1 / * c l e a r I C C 3 . Z i f s t o r e h a p p e n s * /
beq i c c3 ,#0 ,0 b
bralr
.size atomic_ t e s t _ a n d _ A N D N O T _ m a s k , . - a t o m i c _ t e s t _ a n d _ A N D N O T _ m a s k
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# unsigned l o n g a t o m i c _ t e s t _ a n d _ O R _ m a s k ( u n s i g n e d l o n g m a s k , v o l a t i l e u n s i g n e d l o n g * v ) ;
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
.globl atomic_test_and_OR_mask
.type atomic_ t e s t _ a n d _ O R _ m a s k ,@function
atomic_test_and_OR_mask :
or. p g r8 ,g r8 ,g r10
0 :
orcc g r0 ,g r0 ,g r0 ,i c c3 / * s e t I C C 3 . Z * /
ckeq i c c3 ,c c7
ld. p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
orcr c c7 ,c c7 ,c c3 / * s e t C C 3 t o t r u e * /
or g r8 ,g r10 ,g r11
cst. p g r11 ,@(gr9,gr0) ,cc3,#1
corcc g r29 ,g r29 ,g r0 ,c c3 ,#1 / * c l e a r I C C 3 . Z i f s t o r e h a p p e n s * /
beq i c c3 ,#0 ,0 b
bralr
.size atomic_ t e s t _ a n d _ O R _ m a s k , . - a t o m i c _ t e s t _ a n d _ O R _ m a s k
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# unsigned l o n g a t o m i c _ t e s t _ a n d _ X O R _ m a s k ( u n s i g n e d l o n g m a s k , v o l a t i l e u n s i g n e d l o n g * v ) ;
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
.globl atomic_test_and_XOR_mask
.type atomic_ t e s t _ a n d _ X O R _ m a s k ,@function
atomic_test_and_XOR_mask :
or. p g r8 ,g r8 ,g r10
0 :
orcc g r0 ,g r0 ,g r0 ,i c c3 / * s e t I C C 3 . Z * /
ckeq i c c3 ,c c7
ld. p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
orcr c c7 ,c c7 ,c c3 / * s e t C C 3 t o t r u e * /
xor g r8 ,g r10 ,g r11
cst. p g r11 ,@(gr9,gr0) ,cc3,#1
corcc g r29 ,g r29 ,g r0 ,c c3 ,#1 / * c l e a r I C C 3 . Z i f s t o r e h a p p e n s * /
beq i c c3 ,#0 ,0 b
bralr
.size atomic_ t e s t _ a n d _ X O R _ m a s k , . - a t o m i c _ t e s t _ a n d _ X O R _ m a s k
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# int a t o m i c _ a d d _ r e t u r n ( i n t i , a t o m i c _ t * v )
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
.globl atomic_add_return
.type atomic_ a d d _ r e t u r n ,@function
atomic_add_return :
or. p g r8 ,g r8 ,g r10
0 :
orcc g r0 ,g r0 ,g r0 ,i c c3 / * s e t I C C 3 . Z * /
ckeq i c c3 ,c c7
ld. p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
orcr c c7 ,c c7 ,c c3 / * s e t C C 3 t o t r u e * /
add g r8 ,g r10 ,g r8
cst. p g r8 ,@(gr9,gr0) ,cc3,#1
corcc g r29 ,g r29 ,g r0 ,c c3 ,#1 / * c l e a r I C C 3 . Z i f s t o r e h a p p e n s * /
beq i c c3 ,#0 ,0 b
bralr
.size atomic_ a d d _ r e t u r n , . - a t o m i c _ a d d _ r e t u r n
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# int a t o m i c _ s u b _ r e t u r n ( i n t i , a t o m i c _ t * v )
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
.globl atomic_sub_return
.type atomic_ s u b _ r e t u r n ,@function
atomic_sub_return :
or. p g r8 ,g r8 ,g r10
0 :
orcc g r0 ,g r0 ,g r0 ,i c c3 / * s e t I C C 3 . Z * /
ckeq i c c3 ,c c7
ld. p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
orcr c c7 ,c c7 ,c c3 / * s e t C C 3 t o t r u e * /
sub g r8 ,g r10 ,g r8
cst. p g r8 ,@(gr9,gr0) ,cc3,#1
corcc g r29 ,g r29 ,g r0 ,c c3 ,#1 / * c l e a r I C C 3 . Z i f s t o r e h a p p e n s * /
beq i c c3 ,#0 ,0 b
bralr
.size atomic_ s u b _ r e t u r n , . - a t o m i c _ s u b _ r e t u r n
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# uint3 2 _ t _ _ x c h g _ 3 2 ( u i n t 3 2 _ t i , u i n t 3 2 _ t * v )
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
.globl __xchg_32
.type _ _ xchg_ 3 2 ,@function
__xchg_32 :
or. p g r8 ,g r8 ,g r10
0 :
orcc g r0 ,g r0 ,g r0 ,i c c3 / * s e t I C C 3 . Z * /
ckeq i c c3 ,c c7
ld. p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
orcr c c7 ,c c7 ,c c3 / * s e t C C 3 t o t r u e * /
cst. p g r10 ,@(gr9,gr0) ,cc3,#1
corcc g r29 ,g r29 ,g r0 ,c c3 ,#1 / * c l e a r I C C 3 . Z i f s t o r e h a p p e n s * /
beq i c c3 ,#0 ,0 b
bralr
.size _ _ xchg_ 3 2 , . - _ _ x c h g _ 3 2
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# uint3 2 _ t _ _ c m p x c h g _ 3 2 ( u i n t 3 2 _ t * v , u i n t 3 2 _ t t e s t , u i n t 3 2 _ t n e w )
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
.globl __cmpxchg_32
.type _ _ cmpxchg_ 3 2 ,@function
__cmpxchg_32 :
or. p g r8 ,g r8 ,g r11
0 :
orcc g r0 ,g r0 ,g r0 ,i c c3
ckeq i c c3 ,c c7
ld. p @(gr11,gr0),gr8
orcr c c7 ,c c7 ,c c3
subcc g r8 ,g r9 ,g r7 ,i c c0
FRV: Implement atomic64_t
Implement atomic64_t and its ops for FRV. Tested with the following patch:
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index 55e4fab..086d50d 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -746,6 +746,52 @@ static void __init parse_cmdline_early(char *cmdline)
} /* end parse_cmdline_early() */
+static atomic64_t xxx;
+
+static void test_atomic64(void)
+{
+ atomic64_set(&xxx, 0x12300000023LL);
+
+ mb();
+ BUG_ON(atomic64_read(&xxx) != 0x12300000023LL);
+ mb();
+ if (atomic64_inc_return(&xxx) != 0x12300000024LL)
+ BUG();
+ mb();
+ BUG_ON(atomic64_read(&xxx) != 0x12300000024LL);
+ mb();
+ if (atomic64_sub_return(0x36900000050LL, &xxx) != -0x2460000002cLL)
+ BUG();
+ mb();
+ BUG_ON(atomic64_read(&xxx) != -0x2460000002cLL);
+ mb();
+ if (atomic64_dec_return(&xxx) != -0x2460000002dLL)
+ BUG();
+ mb();
+ BUG_ON(atomic64_read(&xxx) != -0x2460000002dLL);
+ mb();
+ if (atomic64_add_return(0x36800000001LL, &xxx) != 0x121ffffffd4LL)
+ BUG();
+ mb();
+ BUG_ON(atomic64_read(&xxx) != 0x121ffffffd4LL);
+ mb();
+ if (atomic64_cmpxchg(&xxx, 0x123456789abcdefLL, 0x121ffffffd4LL) != 0x121ffffffd4LL)
+ BUG();
+ mb();
+ BUG_ON(atomic64_read(&xxx) != 0x121ffffffd4LL);
+ mb();
+ if (atomic64_cmpxchg(&xxx, 0x121ffffffd4LL, 0x123456789abcdefLL) != 0x121ffffffd4LL)
+ BUG();
+ mb();
+ BUG_ON(atomic64_read(&xxx) != 0x123456789abcdefLL);
+ mb();
+ if (atomic64_xchg(&xxx, 0xabcdef123456789LL) != 0x123456789abcdefLL)
+ BUG();
+ mb();
+ BUG_ON(atomic64_read(&xxx) != 0xabcdef123456789LL);
+ mb();
+}
+
/*****************************************************************************/
/*
*
@@ -845,6 +891,8 @@ void __init setup_arch(char **cmdline_p)
// asm volatile("movgs %0,timerd" :: "r"(10000000));
// __set_HSR(0, __get_HSR(0) | HSR0_ETMD);
+ test_atomic64();
+
} /* end setup_arch() */
#if 0
Note that this doesn't cover all the trivial wrappers, but does cover all the
substantial implementations.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-07-02 00:46:16 +01:00
bnelr i c c0 ,#0
2005-04-16 15:20:36 -07:00
cst. p g r10 ,@(gr11,gr0) ,cc3,#1
corcc g r29 ,g r29 ,g r0 ,c c3 ,#1
beq i c c3 ,#0 ,0 b
bralr
.size _ _ cmpxchg_ 3 2 , . - _ _ c m p x c h g _ 3 2