2005-04-16 15:20:36 -07:00
/* bitops.h: bit operations for the Fujitsu FR-V CPUs
*
* For an explanation of how atomic ops work in this arch , see :
2008-02-03 15:54:28 +02:00
* Documentation / frv / atomic - ops . txt
2005-04-16 15:20:36 -07:00
*
* Copyright ( C ) 2004 Red Hat , Inc . All Rights Reserved .
* Written by David Howells ( dhowells @ redhat . com )
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*/
# ifndef _ASM_BITOPS_H
# define _ASM_BITOPS_H
# include <linux/compiler.h>
# include <asm/byteorder.h>
# ifdef __KERNEL__
2007-10-18 23:40:26 -07:00
# ifndef _LINUX_BITOPS_H
# error only <linux / bitops.h> can be included directly
# endif
[PATCH] bitops: frv: use generic bitops
- remove ffz()
- remove find_{next,first}{,_zero}_bit()
- remove generic_ffs()
- remove __ffs()
- remove generic_fls64()
- remove sched_find_first_bit()
- remove generic_hweight{32,16,8}()
- remove ext2_{set,clear,test,find_first_zero,find_next_zero}_bit()
- remove minix_{test,set,test_and_clear,test,find_first_zero}_bit()
Signed-off-by: Akinobu Mita <mita@miraclelinux.com>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-03-26 01:39:22 -08:00
# include <asm-generic/bitops/ffz.h>
2005-04-16 15:20:36 -07:00
/*
* clear_bit ( ) doesn ' t provide any barrier for the compiler .
*/
# define smp_mb__before_clear_bit() barrier()
# define smp_mb__after_clear_bit() barrier()
2008-02-08 15:00:45 -08:00
# ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
static inline
unsigned long atomic_test_and_ANDNOT_mask ( unsigned long mask , volatile unsigned long * v )
{
unsigned long old , tmp ;
asm volatile (
" 0: \n "
" orcc gr0,gr0,gr0,icc3 \n " /* set ICC3.Z */
" ckeq icc3,cc7 \n "
" ld.p %M0,%1 \n " /* LD.P/ORCR are atomic */
" orcr cc7,cc7,cc3 \n " /* set CC3 to true */
" and%I3 %1,%3,%2 \n "
" cst.p %2,%M0 ,cc3,#1 \n " /* if store happens... */
" corcc gr29,gr29,gr0 ,cc3,#1 \n " /* ... clear ICC3.Z */
" beq icc3,#0,0b \n "
: " +U " ( * v ) , " =&r " ( old ) , " =r " ( tmp )
: " NPr " ( ~ mask )
: " memory " , " cc7 " , " cc3 " , " icc3 "
) ;
return old ;
}
static inline
unsigned long atomic_test_and_OR_mask ( unsigned long mask , volatile unsigned long * v )
{
unsigned long old , tmp ;
asm volatile (
" 0: \n "
" orcc gr0,gr0,gr0,icc3 \n " /* set ICC3.Z */
" ckeq icc3,cc7 \n "
" ld.p %M0,%1 \n " /* LD.P/ORCR are atomic */
" orcr cc7,cc7,cc3 \n " /* set CC3 to true */
" or%I3 %1,%3,%2 \n "
" cst.p %2,%M0 ,cc3,#1 \n " /* if store happens... */
" corcc gr29,gr29,gr0 ,cc3,#1 \n " /* ... clear ICC3.Z */
" beq icc3,#0,0b \n "
: " +U " ( * v ) , " =&r " ( old ) , " =r " ( tmp )
: " NPr " ( mask )
: " memory " , " cc7 " , " cc3 " , " icc3 "
) ;
return old ;
}
static inline
unsigned long atomic_test_and_XOR_mask ( unsigned long mask , volatile unsigned long * v )
{
unsigned long old , tmp ;
asm volatile (
" 0: \n "
" orcc gr0,gr0,gr0,icc3 \n " /* set ICC3.Z */
" ckeq icc3,cc7 \n "
" ld.p %M0,%1 \n " /* LD.P/ORCR are atomic */
" orcr cc7,cc7,cc3 \n " /* set CC3 to true */
" xor%I3 %1,%3,%2 \n "
" cst.p %2,%M0 ,cc3,#1 \n " /* if store happens... */
" corcc gr29,gr29,gr0 ,cc3,#1 \n " /* ... clear ICC3.Z */
" beq icc3,#0,0b \n "
: " +U " ( * v ) , " =&r " ( old ) , " =r " ( tmp )
: " NPr " ( mask )
: " memory " , " cc7 " , " cc3 " , " icc3 "
) ;
return old ;
}
# else
extern unsigned long atomic_test_and_ANDNOT_mask ( unsigned long mask , volatile unsigned long * v ) ;
extern unsigned long atomic_test_and_OR_mask ( unsigned long mask , volatile unsigned long * v ) ;
extern unsigned long atomic_test_and_XOR_mask ( unsigned long mask , volatile unsigned long * v ) ;
# endif
# define atomic_clear_mask(mask, v) atomic_test_and_ANDNOT_mask((mask), (v))
# define atomic_set_mask(mask, v) atomic_test_and_OR_mask((mask), (v))
2009-06-11 13:04:59 +01:00
static inline int test_and_clear_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
volatile unsigned long * ptr = addr ;
unsigned long mask = 1UL < < ( nr & 31 ) ;
ptr + = nr > > 5 ;
return ( atomic_test_and_ANDNOT_mask ( mask , ptr ) & mask ) ! = 0 ;
}
2009-06-11 13:04:59 +01:00
static inline int test_and_set_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
volatile unsigned long * ptr = addr ;
unsigned long mask = 1UL < < ( nr & 31 ) ;
ptr + = nr > > 5 ;
return ( atomic_test_and_OR_mask ( mask , ptr ) & mask ) ! = 0 ;
}
2009-06-11 13:04:59 +01:00
static inline int test_and_change_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
volatile unsigned long * ptr = addr ;
unsigned long mask = 1UL < < ( nr & 31 ) ;
ptr + = nr > > 5 ;
return ( atomic_test_and_XOR_mask ( mask , ptr ) & mask ) ! = 0 ;
}
2009-06-11 13:04:59 +01:00
static inline void clear_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
test_and_clear_bit ( nr , addr ) ;
}
2009-06-11 13:04:59 +01:00
static inline void set_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
test_and_set_bit ( nr , addr ) ;
}
2009-06-11 13:04:59 +01:00
static inline void change_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
test_and_change_bit ( nr , addr ) ;
}
2009-06-11 13:04:59 +01:00
static inline void __clear_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
volatile unsigned long * a = addr ;
int mask ;
a + = nr > > 5 ;
mask = 1 < < ( nr & 31 ) ;
* a & = ~ mask ;
}
2009-06-11 13:04:59 +01:00
static inline void __set_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
volatile unsigned long * a = addr ;
int mask ;
a + = nr > > 5 ;
mask = 1 < < ( nr & 31 ) ;
* a | = mask ;
}
2009-06-11 13:04:59 +01:00
static inline void __change_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
volatile unsigned long * a = addr ;
int mask ;
a + = nr > > 5 ;
mask = 1 < < ( nr & 31 ) ;
* a ^ = mask ;
}
2009-06-11 13:04:59 +01:00
static inline int __test_and_clear_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
volatile unsigned long * a = addr ;
int mask , retval ;
a + = nr > > 5 ;
mask = 1 < < ( nr & 31 ) ;
retval = ( mask & * a ) ! = 0 ;
* a & = ~ mask ;
return retval ;
}
2009-06-11 13:04:59 +01:00
static inline int __test_and_set_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
volatile unsigned long * a = addr ;
int mask , retval ;
a + = nr > > 5 ;
mask = 1 < < ( nr & 31 ) ;
retval = ( mask & * a ) ! = 0 ;
* a | = mask ;
return retval ;
}
2009-06-11 13:04:59 +01:00
static inline int __test_and_change_bit ( unsigned long nr , volatile void * addr )
2005-04-16 15:20:36 -07:00
{
volatile unsigned long * a = addr ;
int mask , retval ;
a + = nr > > 5 ;
mask = 1 < < ( nr & 31 ) ;
retval = ( mask & * a ) ! = 0 ;
* a ^ = mask ;
return retval ;
}
/*
* This routine doesn ' t need to be atomic .
*/
2009-06-11 13:04:59 +01:00
static inline int
__constant_test_bit ( unsigned long nr , const volatile void * addr )
2005-04-16 15:20:36 -07:00
{
return ( ( 1UL < < ( nr & 31 ) ) & ( ( ( const volatile unsigned int * ) addr ) [ nr > > 5 ] ) ) ! = 0 ;
}
2009-06-11 13:04:59 +01:00
static inline int __test_bit ( unsigned long nr , const volatile void * addr )
2005-04-16 15:20:36 -07:00
{
int * a = ( int * ) addr ;
int mask ;
a + = nr > > 5 ;
mask = 1 < < ( nr & 0x1f ) ;
return ( ( mask & * a ) ! = 0 ) ;
}
# define test_bit(nr,addr) \
( __builtin_constant_p ( nr ) ? \
__constant_test_bit ( ( nr ) , ( addr ) ) : \
__test_bit ( ( nr ) , ( addr ) ) )
[PATCH] bitops: frv: use generic bitops
- remove ffz()
- remove find_{next,first}{,_zero}_bit()
- remove generic_ffs()
- remove __ffs()
- remove generic_fls64()
- remove sched_find_first_bit()
- remove generic_hweight{32,16,8}()
- remove ext2_{set,clear,test,find_first_zero,find_next_zero}_bit()
- remove minix_{test,set,test_and_clear,test,find_first_zero}_bit()
Signed-off-by: Akinobu Mita <mita@miraclelinux.com>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-03-26 01:39:22 -08:00
# include <asm-generic/bitops/find.h>
2005-04-16 15:20:36 -07:00
2006-09-25 23:32:07 -07:00
/**
* fls - find last bit set
* @ x : the word to search
*
* This is defined the same way as ffs :
* - return 32. .1 to indicate bit 31. .0 most significant bit set
* - return 0 to indicate no bits set
2005-04-16 15:20:36 -07:00
*/
# define fls(x) \
( { \
int bit ; \
\
2006-09-25 23:32:07 -07:00
asm ( " subcc %1,gr0,gr0,icc0 \n " \
" ckne icc0,cc4 \n " \
" cscan.p %1,gr0,%0 ,cc4,#1 \n " \
" csub %0,%0,%0 ,cc4,#0 \n " \
" csub %2,%0,%0 ,cc4,#1 \n " \
: " =&r " ( bit ) \
: " r " ( x ) , " r " ( 32 ) \
: " icc0 " , " cc4 " \
) ; \
2005-04-16 15:20:36 -07:00
\
2006-09-25 23:32:07 -07:00
bit ; \
2005-04-16 15:20:36 -07:00
} )
2006-09-25 23:32:08 -07:00
/**
* fls64 - find last bit set in a 64 - bit value
* @ n : the value to search
*
* This is defined the same way as ffs :
* - return 64. .1 to indicate bit 63. .0 most significant bit set
* - return 0 to indicate no bits set
*/
static inline __attribute__ ( ( const ) )
int fls64 ( u64 n )
{
union {
u64 ll ;
struct { u32 h , l ; } ;
} _ ;
int bit , x , y ;
_ . ll = n ;
asm ( " subcc.p %3,gr0,gr0,icc0 \n "
" subcc %4,gr0,gr0,icc1 \n "
" ckne icc0,cc4 \n "
" ckne icc1,cc5 \n "
" norcr cc4,cc5,cc6 \n "
" csub.p %0,%0,%0 ,cc6,1 \n "
" orcr cc5,cc4,cc4 \n "
" andcr cc4,cc5,cc4 \n "
" cscan.p %3,gr0,%0 ,cc4,0 \n "
" setlos #64,%1 \n "
" cscan.p %4,gr0,%0 ,cc4,1 \n "
" setlos #32,%2 \n "
" csub.p %1,%0,%0 ,cc4,0 \n "
" csub %2,%0,%0 ,cc4,1 \n "
: " =&r " ( bit ) , " =r " ( x ) , " =r " ( y )
: " 0r " ( _ . h ) , " r " ( _ . l )
: " icc0 " , " icc1 " , " cc4 " , " cc5 " , " cc6 "
) ;
return bit ;
}
2006-09-25 23:32:09 -07:00
/**
* ffs - find first bit set
* @ x : the word to search
*
* - return 32. .1 to indicate bit 31. .0 most least significant bit set
* - return 0 to indicate no bits set
*/
static inline __attribute__ ( ( const ) )
int ffs ( int x )
{
/* Note: (x & -x) gives us a mask that is the least significant
* ( rightmost ) 1 - bit of the value in x .
*/
return fls ( x & - x ) ;
}
/**
* __ffs - find first bit set
* @ x : the word to search
*
* - return 31. .0 to indicate bit 31. .0 most least significant bit set
* - if no bits are set in x , the result is undefined
*/
static inline __attribute__ ( ( const ) )
int __ffs ( unsigned long x )
{
int bit ;
asm ( " scan %1,gr0,%0 " : " =r " ( bit ) : " r " ( x & - x ) ) ;
return 31 - bit ;
}
2009-01-03 16:14:05 +10:30
/**
* __fls - find last ( most - significant ) set bit in a long word
* @ word : the word to search
*
* Undefined if no set bit exists , so code should check against 0 first .
*/
static inline unsigned long __fls ( unsigned long word )
{
unsigned long bit ;
asm ( " scan %1,gr0,%0 " : " =r " ( bit ) : " r " ( word ) ) ;
return bit ;
}
2006-12-08 02:37:49 -08:00
/*
* special slimline version of fls ( ) for calculating ilog2_u32 ( )
* - note : no protection against n = = 0
*/
# define ARCH_HAS_ILOG2_U32
static inline __attribute__ ( ( const ) )
int __ilog2_u32 ( u32 n )
{
int bit ;
asm ( " scan %1,gr0,%0 " : " =r " ( bit ) : " r " ( n ) ) ;
return 31 - bit ;
}
/*
* special slimline version of fls64 ( ) for calculating ilog2_u64 ( )
* - note : no protection against n = = 0
*/
# define ARCH_HAS_ILOG2_U64
static inline __attribute__ ( ( const ) )
int __ilog2_u64 ( u64 n )
{
union {
u64 ll ;
struct { u32 h , l ; } ;
} _ ;
int bit , x , y ;
_ . ll = n ;
asm ( " subcc %3,gr0,gr0,icc0 \n "
" ckeq icc0,cc4 \n "
" cscan.p %3,gr0,%0 ,cc4,0 \n "
" setlos #63,%1 \n "
" cscan.p %4,gr0,%0 ,cc4,1 \n "
" setlos #31,%2 \n "
" csub.p %1,%0,%0 ,cc4,0 \n "
" csub %2,%0,%0 ,cc4,1 \n "
: " =&r " ( bit ) , " =r " ( x ) , " =r " ( y )
: " 0r " ( _ . h ) , " r " ( _ . l )
: " icc0 " , " cc4 "
) ;
return bit ;
}
[PATCH] bitops: frv: use generic bitops
- remove ffz()
- remove find_{next,first}{,_zero}_bit()
- remove generic_ffs()
- remove __ffs()
- remove generic_fls64()
- remove sched_find_first_bit()
- remove generic_hweight{32,16,8}()
- remove ext2_{set,clear,test,find_first_zero,find_next_zero}_bit()
- remove minix_{test,set,test_and_clear,test,find_first_zero}_bit()
Signed-off-by: Akinobu Mita <mita@miraclelinux.com>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-03-26 01:39:22 -08:00
# include <asm-generic/bitops/sched.h>
# include <asm-generic/bitops/hweight.h>
2007-10-18 03:06:39 -07:00
# include <asm-generic/bitops/lock.h>
2005-04-16 15:20:36 -07:00
bitops: introduce little-endian bitops for most architectures
Introduce little-endian bit operations to the big-endian architectures
which do not have native little-endian bit operations and the
little-endian architectures. (alpha, avr32, blackfin, cris, frv, h8300,
ia64, m32r, mips, mn10300, parisc, sh, sparc, tile, x86, xtensa)
These architectures can just include generic implementation
(asm-generic/bitops/le.h).
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Mikael Starvik <starvik@axis.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: "Luck, Tony" <tony.luck@intel.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Matthew Wilcox <willy@debian.org>
Cc: Grant Grundler <grundler@parisc-linux.org>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Chris Zankel <chris@zankel.net>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
Acked-by: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2011-03-23 16:42:02 -07:00
# include <asm-generic/bitops/le.h>
2005-04-16 15:20:36 -07:00
2011-07-26 16:09:04 -07:00
# include <asm-generic/bitops/ext2-atomic-setbit.h>
2005-04-16 15:20:36 -07:00
# endif /* __KERNEL__ */
# endif /* _ASM_BITOPS_H */