~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sh/include/asm/bitops-op32.h

Version: ~ [ linux-5.4-rc7 ] ~ [ linux-5.3.11 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.84 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.154 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.201 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.201 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.77 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #ifndef __ASM_SH_BITOPS_OP32_H
  2 #define __ASM_SH_BITOPS_OP32_H
  3 
  4 /*
  5  * The bit modifying instructions on SH-2A are only capable of working
  6  * with a 3-bit immediate, which signifies the shift position for the bit
  7  * being worked on.
  8  */
  9 #if defined(__BIG_ENDIAN)
 10 #define BITOP_LE_SWIZZLE        ((BITS_PER_LONG-1) & ~0x7)
 11 #define BYTE_NUMBER(nr)         ((nr ^ BITOP_LE_SWIZZLE) / BITS_PER_BYTE)
 12 #define BYTE_OFFSET(nr)         ((nr ^ BITOP_LE_SWIZZLE) % BITS_PER_BYTE)
 13 #else
 14 #define BYTE_NUMBER(nr)         ((nr) / BITS_PER_BYTE)
 15 #define BYTE_OFFSET(nr)         ((nr) % BITS_PER_BYTE)
 16 #endif
 17 
 18 #define IS_IMMEDIATE(nr)        (__builtin_constant_p(nr))
 19 
 20 static inline void __set_bit(int nr, volatile unsigned long *addr)
 21 {
 22         if (IS_IMMEDIATE(nr)) {
 23                 __asm__ __volatile__ (
 24                         "bset.b %1, @(%O2,%0)           ! __set_bit\n\t"
 25                         : "+r" (addr)
 26                         : "i" (BYTE_OFFSET(nr)), "i" (BYTE_NUMBER(nr))
 27                         : "t", "memory"
 28                 );
 29         } else {
 30                 unsigned long mask = BIT_MASK(nr);
 31                 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 32 
 33                 *p |= mask;
 34         }
 35 }
 36 
 37 static inline void __clear_bit(int nr, volatile unsigned long *addr)
 38 {
 39         if (IS_IMMEDIATE(nr)) {
 40                 __asm__ __volatile__ (
 41                         "bclr.b %1, @(%O2,%0)           ! __clear_bit\n\t"
 42                         : "+r" (addr)
 43                         : "i" (BYTE_OFFSET(nr)),
 44                           "i" (BYTE_NUMBER(nr))
 45                         : "t", "memory"
 46                 );
 47         } else {
 48                 unsigned long mask = BIT_MASK(nr);
 49                 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 50 
 51                 *p &= ~mask;
 52         }
 53 }
 54 
 55 /**
 56  * __change_bit - Toggle a bit in memory
 57  * @nr: the bit to change
 58  * @addr: the address to start counting from
 59  *
 60  * Unlike change_bit(), this function is non-atomic and may be reordered.
 61  * If it's called on the same region of memory simultaneously, the effect
 62  * may be that only one operation succeeds.
 63  */
 64 static inline void __change_bit(int nr, volatile unsigned long *addr)
 65 {
 66         if (IS_IMMEDIATE(nr)) {
 67                 __asm__ __volatile__ (
 68                         "bxor.b %1, @(%O2,%0)           ! __change_bit\n\t"
 69                         : "+r" (addr)
 70                         : "i" (BYTE_OFFSET(nr)),
 71                           "i" (BYTE_NUMBER(nr))
 72                         : "t", "memory"
 73                 );
 74         } else {
 75                 unsigned long mask = BIT_MASK(nr);
 76                 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 77 
 78                 *p ^= mask;
 79         }
 80 }
 81 
 82 /**
 83  * __test_and_set_bit - Set a bit and return its old value
 84  * @nr: Bit to set
 85  * @addr: Address to count from
 86  *
 87  * This operation is non-atomic and can be reordered.
 88  * If two examples of this operation race, one can appear to succeed
 89  * but actually fail.  You must protect multiple accesses with a lock.
 90  */
 91 static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
 92 {
 93         unsigned long mask = BIT_MASK(nr);
 94         unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 95         unsigned long old = *p;
 96 
 97         *p = old | mask;
 98         return (old & mask) != 0;
 99 }
100 
101 /**
102  * __test_and_clear_bit - Clear a bit and return its old value
103  * @nr: Bit to clear
104  * @addr: Address to count from
105  *
106  * This operation is non-atomic and can be reordered.
107  * If two examples of this operation race, one can appear to succeed
108  * but actually fail.  You must protect multiple accesses with a lock.
109  */
110 static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
111 {
112         unsigned long mask = BIT_MASK(nr);
113         unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
114         unsigned long old = *p;
115 
116         *p = old & ~mask;
117         return (old & mask) != 0;
118 }
119 
120 /* WARNING: non atomic and it can be reordered! */
121 static inline int __test_and_change_bit(int nr,
122                                             volatile unsigned long *addr)
123 {
124         unsigned long mask = BIT_MASK(nr);
125         unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
126         unsigned long old = *p;
127 
128         *p = old ^ mask;
129         return (old & mask) != 0;
130 }
131 
132 /**
133  * test_bit - Determine whether a bit is set
134  * @nr: bit number to test
135  * @addr: Address to start counting from
136  */
137 static inline int test_bit(int nr, const volatile unsigned long *addr)
138 {
139         return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
140 }
141 
142 #endif /* __ASM_SH_BITOPS_OP32_H */
143 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp