Path: blob/master/arch/sh/include/asm/bitops-op32.h
15126 views
#ifndef __ASM_SH_BITOPS_OP32_H1#define __ASM_SH_BITOPS_OP32_H23/*4* The bit modifying instructions on SH-2A are only capable of working5* with a 3-bit immediate, which signifies the shift position for the bit6* being worked on.7*/8#if defined(__BIG_ENDIAN)9#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7)10#define BYTE_NUMBER(nr) ((nr ^ BITOP_LE_SWIZZLE) / BITS_PER_BYTE)11#define BYTE_OFFSET(nr) ((nr ^ BITOP_LE_SWIZZLE) % BITS_PER_BYTE)12#else13#define BYTE_NUMBER(nr) ((nr) / BITS_PER_BYTE)14#define BYTE_OFFSET(nr) ((nr) % BITS_PER_BYTE)15#endif1617#define IS_IMMEDIATE(nr) (__builtin_constant_p(nr))1819static inline void __set_bit(int nr, volatile unsigned long *addr)20{21if (IS_IMMEDIATE(nr)) {22__asm__ __volatile__ (23"bset.b %1, @(%O2,%0) ! __set_bit\n\t"24: "+r" (addr)25: "i" (BYTE_OFFSET(nr)), "i" (BYTE_NUMBER(nr))26: "t", "memory"27);28} else {29unsigned long mask = BIT_MASK(nr);30unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);3132*p |= mask;33}34}3536static inline void __clear_bit(int nr, volatile unsigned long *addr)37{38if (IS_IMMEDIATE(nr)) {39__asm__ __volatile__ (40"bclr.b %1, @(%O2,%0) ! __clear_bit\n\t"41: "+r" (addr)42: "i" (BYTE_OFFSET(nr)),43"i" (BYTE_NUMBER(nr))44: "t", "memory"45);46} else {47unsigned long mask = BIT_MASK(nr);48unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);4950*p &= ~mask;51}52}5354/**55* __change_bit - Toggle a bit in memory56* @nr: the bit to change57* @addr: the address to start counting from58*59* Unlike change_bit(), this function is non-atomic and may be reordered.60* If it's called on the same region of memory simultaneously, the effect61* may be that only one operation succeeds.62*/63static inline void __change_bit(int nr, volatile unsigned long *addr)64{65if (IS_IMMEDIATE(nr)) {66__asm__ __volatile__ (67"bxor.b %1, @(%O2,%0) ! __change_bit\n\t"68: "+r" (addr)69: "i" (BYTE_OFFSET(nr)),70"i" (BYTE_NUMBER(nr))71: "t", "memory"72);73} else {74unsigned long mask = BIT_MASK(nr);75unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);7677*p ^= mask;78}79}8081/**82* __test_and_set_bit - Set a bit and return its old value83* @nr: Bit to set84* @addr: Address to count from85*86* This operation is non-atomic and can be reordered.87* If two examples of this operation race, one can appear to succeed88* but actually fail. You must protect multiple accesses with a lock.89*/90static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)91{92unsigned long mask = BIT_MASK(nr);93unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);94unsigned long old = *p;9596*p = old | mask;97return (old & mask) != 0;98}99100/**101* __test_and_clear_bit - Clear a bit and return its old value102* @nr: Bit to clear103* @addr: Address to count from104*105* This operation is non-atomic and can be reordered.106* If two examples of this operation race, one can appear to succeed107* but actually fail. You must protect multiple accesses with a lock.108*/109static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)110{111unsigned long mask = BIT_MASK(nr);112unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);113unsigned long old = *p;114115*p = old & ~mask;116return (old & mask) != 0;117}118119/* WARNING: non atomic and it can be reordered! */120static inline int __test_and_change_bit(int nr,121volatile unsigned long *addr)122{123unsigned long mask = BIT_MASK(nr);124unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);125unsigned long old = *p;126127*p = old ^ mask;128return (old & mask) != 0;129}130131/**132* test_bit - Determine whether a bit is set133* @nr: bit number to test134* @addr: Address to start counting from135*/136static inline int test_bit(int nr, const volatile unsigned long *addr)137{138return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));139}140141#endif /* __ASM_SH_BITOPS_OP32_H */142143144