xref: /openbmc/u-boot/arch/sh/include/asm/bitops.h (revision 50e24381)
1819833afSPeter Tyser #ifndef __ASM_SH_BITOPS_H
2819833afSPeter Tyser #define __ASM_SH_BITOPS_H
3819833afSPeter Tyser 
4f86411b1SFabio Estevam #include <asm-generic/bitops/fls.h>
5f86411b1SFabio Estevam #include <asm-generic/bitops/__fls.h>
6f86411b1SFabio Estevam #include <asm-generic/bitops/fls64.h>
7f86411b1SFabio Estevam #include <asm-generic/bitops/__ffs.h>
8f86411b1SFabio Estevam 
9819833afSPeter Tyser #ifdef __KERNEL__
10819833afSPeter Tyser #include <asm/irqflags.h>
11819833afSPeter Tyser /* For __swab32 */
12819833afSPeter Tyser #include <asm/byteorder.h>
13819833afSPeter Tyser 
set_bit(int nr,volatile void * addr)14819833afSPeter Tyser static inline void set_bit(int nr, volatile void * addr)
15819833afSPeter Tyser {
16819833afSPeter Tyser 	int	mask;
17819833afSPeter Tyser 	volatile unsigned int *a = addr;
18819833afSPeter Tyser 	unsigned long flags;
19819833afSPeter Tyser 
20819833afSPeter Tyser 	a += nr >> 5;
21819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
22819833afSPeter Tyser 	local_irq_save(flags);
23819833afSPeter Tyser 	*a |= mask;
24819833afSPeter Tyser 	local_irq_restore(flags);
25819833afSPeter Tyser }
26819833afSPeter Tyser 
27819833afSPeter Tyser /*
28819833afSPeter Tyser  * clear_bit() doesn't provide any barrier for the compiler.
29819833afSPeter Tyser  */
30819833afSPeter Tyser #define smp_mb__before_clear_bit()	barrier()
31819833afSPeter Tyser #define smp_mb__after_clear_bit()	barrier()
clear_bit(int nr,volatile void * addr)32819833afSPeter Tyser static inline void clear_bit(int nr, volatile void * addr)
33819833afSPeter Tyser {
34819833afSPeter Tyser 	int	mask;
35819833afSPeter Tyser 	volatile unsigned int *a = addr;
36819833afSPeter Tyser 	unsigned long flags;
37819833afSPeter Tyser 
38819833afSPeter Tyser 	a += nr >> 5;
39819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
40819833afSPeter Tyser 	local_irq_save(flags);
41819833afSPeter Tyser 	*a &= ~mask;
42819833afSPeter Tyser 	local_irq_restore(flags);
43819833afSPeter Tyser }
44819833afSPeter Tyser 
change_bit(int nr,volatile void * addr)45819833afSPeter Tyser static inline void change_bit(int nr, volatile void * addr)
46819833afSPeter Tyser {
47819833afSPeter Tyser 	int	mask;
48819833afSPeter Tyser 	volatile unsigned int *a = addr;
49819833afSPeter Tyser 	unsigned long flags;
50819833afSPeter Tyser 
51819833afSPeter Tyser 	a += nr >> 5;
52819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
53819833afSPeter Tyser 	local_irq_save(flags);
54819833afSPeter Tyser 	*a ^= mask;
55819833afSPeter Tyser 	local_irq_restore(flags);
56819833afSPeter Tyser }
57819833afSPeter Tyser 
test_and_set_bit(int nr,volatile void * addr)58819833afSPeter Tyser static inline int test_and_set_bit(int nr, volatile void * addr)
59819833afSPeter Tyser {
60819833afSPeter Tyser 	int	mask, retval;
61819833afSPeter Tyser 	volatile unsigned int *a = addr;
62819833afSPeter Tyser 	unsigned long flags;
63819833afSPeter Tyser 
64819833afSPeter Tyser 	a += nr >> 5;
65819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
66819833afSPeter Tyser 	local_irq_save(flags);
67819833afSPeter Tyser 	retval = (mask & *a) != 0;
68819833afSPeter Tyser 	*a |= mask;
69819833afSPeter Tyser 	local_irq_restore(flags);
70819833afSPeter Tyser 
71819833afSPeter Tyser 	return retval;
72819833afSPeter Tyser }
73819833afSPeter Tyser 
test_and_clear_bit(int nr,volatile void * addr)74819833afSPeter Tyser static inline int test_and_clear_bit(int nr, volatile void * addr)
75819833afSPeter Tyser {
76819833afSPeter Tyser 	int	mask, retval;
77819833afSPeter Tyser 	volatile unsigned int *a = addr;
78819833afSPeter Tyser 	unsigned long flags;
79819833afSPeter Tyser 
80819833afSPeter Tyser 	a += nr >> 5;
81819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
82819833afSPeter Tyser 	local_irq_save(flags);
83819833afSPeter Tyser 	retval = (mask & *a) != 0;
84819833afSPeter Tyser 	*a &= ~mask;
85819833afSPeter Tyser 	local_irq_restore(flags);
86819833afSPeter Tyser 
87819833afSPeter Tyser 	return retval;
88819833afSPeter Tyser }
89819833afSPeter Tyser 
test_and_change_bit(int nr,volatile void * addr)90819833afSPeter Tyser static inline int test_and_change_bit(int nr, volatile void * addr)
91819833afSPeter Tyser {
92819833afSPeter Tyser 	int	mask, retval;
93819833afSPeter Tyser 	volatile unsigned int *a = addr;
94819833afSPeter Tyser 	unsigned long flags;
95819833afSPeter Tyser 
96819833afSPeter Tyser 	a += nr >> 5;
97819833afSPeter Tyser 	mask = 1 << (nr & 0x1f);
98819833afSPeter Tyser 	local_irq_save(flags);
99819833afSPeter Tyser 	retval = (mask & *a) != 0;
100819833afSPeter Tyser 	*a ^= mask;
101819833afSPeter Tyser 	local_irq_restore(flags);
102819833afSPeter Tyser 
103819833afSPeter Tyser 	return retval;
104819833afSPeter Tyser }
105819833afSPeter Tyser 
ffz(unsigned long word)106819833afSPeter Tyser static inline unsigned long ffz(unsigned long word)
107819833afSPeter Tyser {
108819833afSPeter Tyser 	unsigned long result;
109819833afSPeter Tyser 
110819833afSPeter Tyser 	__asm__("1:\n\t"
111819833afSPeter Tyser 		"shlr	%1\n\t"
112819833afSPeter Tyser 		"bt/s	1b\n\t"
113819833afSPeter Tyser 		" add	#1, %0"
114819833afSPeter Tyser 		: "=r" (result), "=r" (word)
115819833afSPeter Tyser 		: "0" (~0L), "1" (word)
116819833afSPeter Tyser 		: "t");
117819833afSPeter Tyser 	return result;
118819833afSPeter Tyser }
119819833afSPeter Tyser 
120819833afSPeter Tyser /**
121819833afSPeter Tyser  * ffs - find first bit in word.
122819833afSPeter Tyser  * @word: The word to search
123819833afSPeter Tyser  *
124819833afSPeter Tyser  * Undefined if no bit exists, so code should check against 0 first.
125819833afSPeter Tyser  */
ffs(int x)126819833afSPeter Tyser static inline int ffs (int x)
127819833afSPeter Tyser {
128819833afSPeter Tyser 	int r = 1;
129819833afSPeter Tyser 
130819833afSPeter Tyser 	if (!x)
131819833afSPeter Tyser 		return 0;
132819833afSPeter Tyser 	if (!(x & 0xffff)) {
133819833afSPeter Tyser 		x >>= 16;
134819833afSPeter Tyser 		r += 16;
135819833afSPeter Tyser 	}
136819833afSPeter Tyser 	if (!(x & 0xff)) {
137819833afSPeter Tyser 		x >>= 8;
138819833afSPeter Tyser 		r += 8;
139819833afSPeter Tyser 	}
140819833afSPeter Tyser 	if (!(x & 0xf)) {
141819833afSPeter Tyser 		x >>= 4;
142819833afSPeter Tyser 		r += 4;
143819833afSPeter Tyser 	}
144819833afSPeter Tyser 	if (!(x & 3)) {
145819833afSPeter Tyser 		x >>= 2;
146819833afSPeter Tyser 		r += 2;
147819833afSPeter Tyser 	}
148819833afSPeter Tyser 	if (!(x & 1)) {
149819833afSPeter Tyser 		x >>= 1;
150819833afSPeter Tyser 		r += 1;
151819833afSPeter Tyser 	}
152819833afSPeter Tyser 	return r;
153819833afSPeter Tyser }
154819833afSPeter Tyser #define PLATFORM_FFS
155819833afSPeter Tyser 
156*ce13c19fSVignesh R #define hweight32(x) generic_hweight32(x)
157*ce13c19fSVignesh R #define hweight16(x) generic_hweight16(x)
158*ce13c19fSVignesh R #define hweight8(x) generic_hweight8(x)
159*ce13c19fSVignesh R 
160819833afSPeter Tyser #endif /* __KERNEL__ */
161819833afSPeter Tyser 
162819833afSPeter Tyser #endif /* __ASM_SH_BITOPS_H */
163