xref: /openbmc/linux/arch/s390/include/asm/bitops.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2c6557e7fSMartin Schwidefsky /*
3746479cdSHeiko Carstens  *    Copyright IBM Corp. 1999,2013
4c6557e7fSMartin Schwidefsky  *
5746479cdSHeiko Carstens  *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
6746479cdSHeiko Carstens  *
7746479cdSHeiko Carstens  * The description below was taken in large parts from the powerpc
8746479cdSHeiko Carstens  * bitops header file:
9746479cdSHeiko Carstens  * Within a word, bits are numbered LSB first.  Lot's of places make
10746479cdSHeiko Carstens  * this assumption by directly testing bits with (val & (1<<nr)).
11746479cdSHeiko Carstens  * This can cause confusion for large (> 1 word) bitmaps on a
12746479cdSHeiko Carstens  * big-endian system because, unlike little endian, the number of each
13746479cdSHeiko Carstens  * bit depends on the word size.
14746479cdSHeiko Carstens  *
1548002bd5SHeiko Carstens  * The bitop functions are defined to work on unsigned longs, so the bits
1648002bd5SHeiko Carstens  * end up numbered:
17db85eaebSHeiko Carstens  *   |63..............0|127............64|191...........128|255...........192|
18746479cdSHeiko Carstens  *
1948002bd5SHeiko Carstens  * We also have special functions which work with an MSB0 encoding.
2048002bd5SHeiko Carstens  * The bits are numbered:
21746479cdSHeiko Carstens  *   |0..............63|64............127|128...........191|192...........255|
22746479cdSHeiko Carstens  *
2348002bd5SHeiko Carstens  * The main difference is that bit 0-63 in the bit number field needs to be
2448002bd5SHeiko Carstens  * reversed compared to the LSB0 encoded bit fields. This can be achieved by
2548002bd5SHeiko Carstens  * XOR with 0x3f.
26c6557e7fSMartin Schwidefsky  *
27c6557e7fSMartin Schwidefsky  */
28c6557e7fSMartin Schwidefsky 
29a53c8fabSHeiko Carstens #ifndef _S390_BITOPS_H
30a53c8fabSHeiko Carstens #define _S390_BITOPS_H
31a53c8fabSHeiko Carstens 
32c6557e7fSMartin Schwidefsky #ifndef _LINUX_BITOPS_H
33c6557e7fSMartin Schwidefsky #error only <linux/bitops.h> can be included directly
34c6557e7fSMartin Schwidefsky #endif
35c6557e7fSMartin Schwidefsky 
36370b0b5fSHeiko Carstens #include <linux/typecheck.h>
37c6557e7fSMartin Schwidefsky #include <linux/compiler.h>
380a5c3c2fSVasily Gorbik #include <linux/types.h>
391993dbc7SMartin Schwidefsky #include <asm/atomic_ops.h>
400ccc8b7aSHeiko Carstens #include <asm/barrier.h>
410ccc8b7aSHeiko Carstens 
4201c2475fSAkinobu Mita #define __BITOPS_WORDS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG)
43c6557e7fSMartin Schwidefsky 
44370b0b5fSHeiko Carstens static inline unsigned long *
__bitops_word(unsigned long nr,const volatile unsigned long * ptr)456000b5f4SHeiko Carstens __bitops_word(unsigned long nr, const volatile unsigned long *ptr)
46c6557e7fSMartin Schwidefsky {
47370b0b5fSHeiko Carstens 	unsigned long addr;
48c6557e7fSMartin Schwidefsky 
49370b0b5fSHeiko Carstens 	addr = (unsigned long)ptr + ((nr ^ (nr & (BITS_PER_LONG - 1))) >> 3);
50370b0b5fSHeiko Carstens 	return (unsigned long *)addr;
51370b0b5fSHeiko Carstens }
52370b0b5fSHeiko Carstens 
__bitops_mask(unsigned long nr)536000b5f4SHeiko Carstens static inline unsigned long __bitops_mask(unsigned long nr)
54370b0b5fSHeiko Carstens {
556000b5f4SHeiko Carstens 	return 1UL << (nr & (BITS_PER_LONG - 1));
56370b0b5fSHeiko Carstens }
57370b0b5fSHeiko Carstens 
arch_set_bit(unsigned long nr,volatile unsigned long * ptr)58b4fd5a0aSHeiko Carstens static __always_inline void arch_set_bit(unsigned long nr, volatile unsigned long *ptr)
59370b0b5fSHeiko Carstens {
60370b0b5fSHeiko Carstens 	unsigned long *addr = __bitops_word(nr, ptr);
616000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
62370b0b5fSHeiko Carstens 
634ae98789SArnd Bergmann 	__atomic64_or(mask, (long *)addr);
64c6557e7fSMartin Schwidefsky }
65c6557e7fSMartin Schwidefsky 
arch_clear_bit(unsigned long nr,volatile unsigned long * ptr)66b4fd5a0aSHeiko Carstens static __always_inline void arch_clear_bit(unsigned long nr, volatile unsigned long *ptr)
67c6557e7fSMartin Schwidefsky {
68370b0b5fSHeiko Carstens 	unsigned long *addr = __bitops_word(nr, ptr);
696000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
70c6557e7fSMartin Schwidefsky 
716000b5f4SHeiko Carstens 	__atomic64_and(~mask, (long *)addr);
72c6557e7fSMartin Schwidefsky }
73c6557e7fSMartin Schwidefsky 
arch_change_bit(unsigned long nr,volatile unsigned long * ptr)74b4fd5a0aSHeiko Carstens static __always_inline void arch_change_bit(unsigned long nr,
759779048dSVasily Gorbik 					    volatile unsigned long *ptr)
76c6557e7fSMartin Schwidefsky {
77370b0b5fSHeiko Carstens 	unsigned long *addr = __bitops_word(nr, ptr);
786000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
79c6557e7fSMartin Schwidefsky 
804ae98789SArnd Bergmann 	__atomic64_xor(mask, (long *)addr);
81c6557e7fSMartin Schwidefsky }
82c6557e7fSMartin Schwidefsky 
arch_test_and_set_bit(unsigned long nr,volatile unsigned long * ptr)839779048dSVasily Gorbik static inline bool arch_test_and_set_bit(unsigned long nr,
849779048dSVasily Gorbik 					 volatile unsigned long *ptr)
85c6557e7fSMartin Schwidefsky {
86370b0b5fSHeiko Carstens 	unsigned long *addr = __bitops_word(nr, ptr);
876000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
886000b5f4SHeiko Carstens 	unsigned long old;
89c6557e7fSMartin Schwidefsky 
904ae98789SArnd Bergmann 	old = __atomic64_or_barrier(mask, (long *)addr);
916000b5f4SHeiko Carstens 	return old & mask;
92c6557e7fSMartin Schwidefsky }
93c6557e7fSMartin Schwidefsky 
arch_test_and_clear_bit(unsigned long nr,volatile unsigned long * ptr)949779048dSVasily Gorbik static inline bool arch_test_and_clear_bit(unsigned long nr,
959779048dSVasily Gorbik 					   volatile unsigned long *ptr)
96c6557e7fSMartin Schwidefsky {
97370b0b5fSHeiko Carstens 	unsigned long *addr = __bitops_word(nr, ptr);
986000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
996000b5f4SHeiko Carstens 	unsigned long old;
100c6557e7fSMartin Schwidefsky 
1016000b5f4SHeiko Carstens 	old = __atomic64_and_barrier(~mask, (long *)addr);
1026000b5f4SHeiko Carstens 	return old & mask;
103c6557e7fSMartin Schwidefsky }
104c6557e7fSMartin Schwidefsky 
arch_test_and_change_bit(unsigned long nr,volatile unsigned long * ptr)1059779048dSVasily Gorbik static inline bool arch_test_and_change_bit(unsigned long nr,
1069779048dSVasily Gorbik 					    volatile unsigned long *ptr)
107c6557e7fSMartin Schwidefsky {
108370b0b5fSHeiko Carstens 	unsigned long *addr = __bitops_word(nr, ptr);
1096000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
1106000b5f4SHeiko Carstens 	unsigned long old;
111c6557e7fSMartin Schwidefsky 
1124ae98789SArnd Bergmann 	old = __atomic64_xor_barrier(mask, (long *)addr);
1136000b5f4SHeiko Carstens 	return old & mask;
114c6557e7fSMartin Schwidefsky }
115c6557e7fSMartin Schwidefsky 
1160e862838SAlexander Lobakin static __always_inline void
arch___set_bit(unsigned long nr,volatile unsigned long * addr)1170e862838SAlexander Lobakin arch___set_bit(unsigned long nr, volatile unsigned long *addr)
118c6557e7fSMartin Schwidefsky {
1190e862838SAlexander Lobakin 	unsigned long *p = __bitops_word(nr, addr);
1206000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
121c6557e7fSMartin Schwidefsky 
1220e862838SAlexander Lobakin 	*p |= mask;
123c6557e7fSMartin Schwidefsky }
124c6557e7fSMartin Schwidefsky 
1250e862838SAlexander Lobakin static __always_inline void
arch___clear_bit(unsigned long nr,volatile unsigned long * addr)1260e862838SAlexander Lobakin arch___clear_bit(unsigned long nr, volatile unsigned long *addr)
127c6557e7fSMartin Schwidefsky {
1280e862838SAlexander Lobakin 	unsigned long *p = __bitops_word(nr, addr);
1296000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
130c6557e7fSMartin Schwidefsky 
1310e862838SAlexander Lobakin 	*p &= ~mask;
132c6557e7fSMartin Schwidefsky }
133c6557e7fSMartin Schwidefsky 
1340e862838SAlexander Lobakin static __always_inline void
arch___change_bit(unsigned long nr,volatile unsigned long * addr)1350e862838SAlexander Lobakin arch___change_bit(unsigned long nr, volatile unsigned long *addr)
136c6557e7fSMartin Schwidefsky {
1370e862838SAlexander Lobakin 	unsigned long *p = __bitops_word(nr, addr);
1386000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
139c6557e7fSMartin Schwidefsky 
1400e862838SAlexander Lobakin 	*p ^= mask;
141c6557e7fSMartin Schwidefsky }
142c6557e7fSMartin Schwidefsky 
1430e862838SAlexander Lobakin static __always_inline bool
arch___test_and_set_bit(unsigned long nr,volatile unsigned long * addr)1440e862838SAlexander Lobakin arch___test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
145c6557e7fSMartin Schwidefsky {
1460e862838SAlexander Lobakin 	unsigned long *p = __bitops_word(nr, addr);
1476000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
1486000b5f4SHeiko Carstens 	unsigned long old;
149c6557e7fSMartin Schwidefsky 
1500e862838SAlexander Lobakin 	old = *p;
1510e862838SAlexander Lobakin 	*p |= mask;
1526000b5f4SHeiko Carstens 	return old & mask;
153c6557e7fSMartin Schwidefsky }
154c6557e7fSMartin Schwidefsky 
1550e862838SAlexander Lobakin static __always_inline bool
arch___test_and_clear_bit(unsigned long nr,volatile unsigned long * addr)1560e862838SAlexander Lobakin arch___test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
157370b0b5fSHeiko Carstens {
1580e862838SAlexander Lobakin 	unsigned long *p = __bitops_word(nr, addr);
1596000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
1606000b5f4SHeiko Carstens 	unsigned long old;
161370b0b5fSHeiko Carstens 
1620e862838SAlexander Lobakin 	old = *p;
1630e862838SAlexander Lobakin 	*p &= ~mask;
1646000b5f4SHeiko Carstens 	return old & mask;
165c6557e7fSMartin Schwidefsky }
166c6557e7fSMartin Schwidefsky 
1670e862838SAlexander Lobakin static __always_inline bool
arch___test_and_change_bit(unsigned long nr,volatile unsigned long * addr)1680e862838SAlexander Lobakin arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
169370b0b5fSHeiko Carstens {
1700e862838SAlexander Lobakin 	unsigned long *p = __bitops_word(nr, addr);
1716000b5f4SHeiko Carstens 	unsigned long mask = __bitops_mask(nr);
1726000b5f4SHeiko Carstens 	unsigned long old;
173370b0b5fSHeiko Carstens 
1740e862838SAlexander Lobakin 	old = *p;
1750e862838SAlexander Lobakin 	*p ^= mask;
1766000b5f4SHeiko Carstens 	return old & mask;
177370b0b5fSHeiko Carstens }
178370b0b5fSHeiko Carstens 
179*d6ffe606SMikulas Patocka #define arch_test_bit generic_test_bit
180*d6ffe606SMikulas Patocka #define arch_test_bit_acquire generic_test_bit_acquire
181c6557e7fSMartin Schwidefsky 
arch_test_and_set_bit_lock(unsigned long nr,volatile unsigned long * ptr)1829779048dSVasily Gorbik static inline bool arch_test_and_set_bit_lock(unsigned long nr,
183acdc9fc9SMartin Schwidefsky 					      volatile unsigned long *ptr)
184acdc9fc9SMartin Schwidefsky {
1859779048dSVasily Gorbik 	if (arch_test_bit(nr, ptr))
186ff7a1eefSHuilong Deng 		return true;
1879779048dSVasily Gorbik 	return arch_test_and_set_bit(nr, ptr);
188acdc9fc9SMartin Schwidefsky }
189acdc9fc9SMartin Schwidefsky 
arch_clear_bit_unlock(unsigned long nr,volatile unsigned long * ptr)1909779048dSVasily Gorbik static inline void arch_clear_bit_unlock(unsigned long nr,
191acdc9fc9SMartin Schwidefsky 					 volatile unsigned long *ptr)
192acdc9fc9SMartin Schwidefsky {
193acdc9fc9SMartin Schwidefsky 	smp_mb__before_atomic();
1949779048dSVasily Gorbik 	arch_clear_bit(nr, ptr);
195acdc9fc9SMartin Schwidefsky }
196acdc9fc9SMartin Schwidefsky 
arch___clear_bit_unlock(unsigned long nr,volatile unsigned long * ptr)1979779048dSVasily Gorbik static inline void arch___clear_bit_unlock(unsigned long nr,
198acdc9fc9SMartin Schwidefsky 					   volatile unsigned long *ptr)
199acdc9fc9SMartin Schwidefsky {
200acdc9fc9SMartin Schwidefsky 	smp_mb();
2019779048dSVasily Gorbik 	arch___clear_bit(nr, ptr);
202acdc9fc9SMartin Schwidefsky }
203acdc9fc9SMartin Schwidefsky 
20481d2c6f8SDaniel Axtens #include <asm-generic/bitops/instrumented-atomic.h>
20581d2c6f8SDaniel Axtens #include <asm-generic/bitops/instrumented-non-atomic.h>
20681d2c6f8SDaniel Axtens #include <asm-generic/bitops/instrumented-lock.h>
2079779048dSVasily Gorbik 
208c6557e7fSMartin Schwidefsky /*
2097d7c7b24SHeiko Carstens  * Functions which use MSB0 bit numbering.
21048002bd5SHeiko Carstens  * The bits are numbered:
2117d7c7b24SHeiko Carstens  *   |0..............63|64............127|128...........191|192...........255|
212c6557e7fSMartin Schwidefsky  */
2137d7c7b24SHeiko Carstens unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size);
2147d7c7b24SHeiko Carstens unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size,
215746479cdSHeiko Carstens 				unsigned long offset);
216c6557e7fSMartin Schwidefsky 
21709214545SHeiko Carstens #define for_each_set_bit_inv(bit, addr, size)				\
21809214545SHeiko Carstens 	for ((bit) = find_first_bit_inv((addr), (size));		\
21909214545SHeiko Carstens 	     (bit) < (size);						\
22009214545SHeiko Carstens 	     (bit) = find_next_bit_inv((addr), (size), (bit) + 1))
22109214545SHeiko Carstens 
set_bit_inv(unsigned long nr,volatile unsigned long * ptr)2227d7c7b24SHeiko Carstens static inline void set_bit_inv(unsigned long nr, volatile unsigned long *ptr)
2237d7c7b24SHeiko Carstens {
2247d7c7b24SHeiko Carstens 	return set_bit(nr ^ (BITS_PER_LONG - 1), ptr);
2257d7c7b24SHeiko Carstens }
2267d7c7b24SHeiko Carstens 
clear_bit_inv(unsigned long nr,volatile unsigned long * ptr)2277d7c7b24SHeiko Carstens static inline void clear_bit_inv(unsigned long nr, volatile unsigned long *ptr)
2287d7c7b24SHeiko Carstens {
2297d7c7b24SHeiko Carstens 	return clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
2307d7c7b24SHeiko Carstens }
2317d7c7b24SHeiko Carstens 
test_and_clear_bit_inv(unsigned long nr,volatile unsigned long * ptr)2320a5c3c2fSVasily Gorbik static inline bool test_and_clear_bit_inv(unsigned long nr,
2330a5c3c2fSVasily Gorbik 					  volatile unsigned long *ptr)
234f3ec471aSJens Freimann {
235f3ec471aSJens Freimann 	return test_and_clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
236f3ec471aSJens Freimann }
237f3ec471aSJens Freimann 
__set_bit_inv(unsigned long nr,volatile unsigned long * ptr)2387d7c7b24SHeiko Carstens static inline void __set_bit_inv(unsigned long nr, volatile unsigned long *ptr)
2397d7c7b24SHeiko Carstens {
2407d7c7b24SHeiko Carstens 	return __set_bit(nr ^ (BITS_PER_LONG - 1), ptr);
2417d7c7b24SHeiko Carstens }
2427d7c7b24SHeiko Carstens 
__clear_bit_inv(unsigned long nr,volatile unsigned long * ptr)2437d7c7b24SHeiko Carstens static inline void __clear_bit_inv(unsigned long nr, volatile unsigned long *ptr)
2447d7c7b24SHeiko Carstens {
2457d7c7b24SHeiko Carstens 	return __clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
2467d7c7b24SHeiko Carstens }
2477d7c7b24SHeiko Carstens 
test_bit_inv(unsigned long nr,const volatile unsigned long * ptr)2480a5c3c2fSVasily Gorbik static inline bool test_bit_inv(unsigned long nr,
2497d7c7b24SHeiko Carstens 				const volatile unsigned long *ptr)
2507d7c7b24SHeiko Carstens {
2517d7c7b24SHeiko Carstens 	return test_bit(nr ^ (BITS_PER_LONG - 1), ptr);
2527d7c7b24SHeiko Carstens }
2537d7c7b24SHeiko Carstens 
254b1cb7e2bSHeiko Carstens /**
255b1cb7e2bSHeiko Carstens  * __flogr - find leftmost one
256b1cb7e2bSHeiko Carstens  * @word - The word to search
257b1cb7e2bSHeiko Carstens  *
258b1cb7e2bSHeiko Carstens  * Returns the bit number of the most significant bit set,
259b1cb7e2bSHeiko Carstens  * where the most significant bit has bit number 0.
260b1cb7e2bSHeiko Carstens  * If no bit is set this function returns 64.
261b1cb7e2bSHeiko Carstens  */
__flogr(unsigned long word)262b1cb7e2bSHeiko Carstens static inline unsigned char __flogr(unsigned long word)
263b1cb7e2bSHeiko Carstens {
264b1cb7e2bSHeiko Carstens 	if (__builtin_constant_p(word)) {
265b1cb7e2bSHeiko Carstens 		unsigned long bit = 0;
266b1cb7e2bSHeiko Carstens 
267b1cb7e2bSHeiko Carstens 		if (!word)
268b1cb7e2bSHeiko Carstens 			return 64;
269b1cb7e2bSHeiko Carstens 		if (!(word & 0xffffffff00000000UL)) {
270b1cb7e2bSHeiko Carstens 			word <<= 32;
271b1cb7e2bSHeiko Carstens 			bit += 32;
272b1cb7e2bSHeiko Carstens 		}
273b1cb7e2bSHeiko Carstens 		if (!(word & 0xffff000000000000UL)) {
274b1cb7e2bSHeiko Carstens 			word <<= 16;
275b1cb7e2bSHeiko Carstens 			bit += 16;
276b1cb7e2bSHeiko Carstens 		}
277b1cb7e2bSHeiko Carstens 		if (!(word & 0xff00000000000000UL)) {
278b1cb7e2bSHeiko Carstens 			word <<= 8;
279b1cb7e2bSHeiko Carstens 			bit += 8;
280b1cb7e2bSHeiko Carstens 		}
281b1cb7e2bSHeiko Carstens 		if (!(word & 0xf000000000000000UL)) {
282b1cb7e2bSHeiko Carstens 			word <<= 4;
283b1cb7e2bSHeiko Carstens 			bit += 4;
284b1cb7e2bSHeiko Carstens 		}
285b1cb7e2bSHeiko Carstens 		if (!(word & 0xc000000000000000UL)) {
286b1cb7e2bSHeiko Carstens 			word <<= 2;
287b1cb7e2bSHeiko Carstens 			bit += 2;
288b1cb7e2bSHeiko Carstens 		}
289b1cb7e2bSHeiko Carstens 		if (!(word & 0x8000000000000000UL)) {
290b1cb7e2bSHeiko Carstens 			word <<= 1;
291b1cb7e2bSHeiko Carstens 			bit += 1;
292b1cb7e2bSHeiko Carstens 		}
293b1cb7e2bSHeiko Carstens 		return bit;
294b1cb7e2bSHeiko Carstens 	} else {
2954f38c7aeSHeiko Carstens 		union register_pair rp;
296b1cb7e2bSHeiko Carstens 
2974f38c7aeSHeiko Carstens 		rp.even = word;
298b1cb7e2bSHeiko Carstens 		asm volatile(
2994f38c7aeSHeiko Carstens 			"       flogr   %[rp],%[rp]\n"
3004f38c7aeSHeiko Carstens 			: [rp] "+d" (rp.pair) : : "cc");
3014f38c7aeSHeiko Carstens 		return rp.even;
302b1cb7e2bSHeiko Carstens 	}
303b1cb7e2bSHeiko Carstens }
304b1cb7e2bSHeiko Carstens 
305b1cb7e2bSHeiko Carstens /**
306b1cb7e2bSHeiko Carstens  * __ffs - find first bit in word.
307b1cb7e2bSHeiko Carstens  * @word: The word to search
308b1cb7e2bSHeiko Carstens  *
309b1cb7e2bSHeiko Carstens  * Undefined if no bit exists, so code should check against 0 first.
310b1cb7e2bSHeiko Carstens  */
__ffs(unsigned long word)311b1cb7e2bSHeiko Carstens static inline unsigned long __ffs(unsigned long word)
312b1cb7e2bSHeiko Carstens {
313b1cb7e2bSHeiko Carstens 	return __flogr(-word & word) ^ (BITS_PER_LONG - 1);
314b1cb7e2bSHeiko Carstens }
315b1cb7e2bSHeiko Carstens 
316b1cb7e2bSHeiko Carstens /**
317b1cb7e2bSHeiko Carstens  * ffs - find first bit set
318b1cb7e2bSHeiko Carstens  * @word: the word to search
319b1cb7e2bSHeiko Carstens  *
320b1cb7e2bSHeiko Carstens  * This is defined the same way as the libc and
321b1cb7e2bSHeiko Carstens  * compiler builtin ffs routines (man ffs).
322b1cb7e2bSHeiko Carstens  */
ffs(int word)323b1cb7e2bSHeiko Carstens static inline int ffs(int word)
324b1cb7e2bSHeiko Carstens {
325b1cb7e2bSHeiko Carstens 	unsigned long mask = 2 * BITS_PER_LONG - 1;
326b1cb7e2bSHeiko Carstens 	unsigned int val = (unsigned int)word;
327b1cb7e2bSHeiko Carstens 
328b1cb7e2bSHeiko Carstens 	return (1 + (__flogr(-val & val) ^ (BITS_PER_LONG - 1))) & mask;
329b1cb7e2bSHeiko Carstens }
330b1cb7e2bSHeiko Carstens 
331b1cb7e2bSHeiko Carstens /**
332b1cb7e2bSHeiko Carstens  * __fls - find last (most-significant) set bit in a long word
333b1cb7e2bSHeiko Carstens  * @word: the word to search
334b1cb7e2bSHeiko Carstens  *
335b1cb7e2bSHeiko Carstens  * Undefined if no set bit exists, so code should check against 0 first.
336b1cb7e2bSHeiko Carstens  */
__fls(unsigned long word)337b1cb7e2bSHeiko Carstens static inline unsigned long __fls(unsigned long word)
338b1cb7e2bSHeiko Carstens {
339b1cb7e2bSHeiko Carstens 	return __flogr(word) ^ (BITS_PER_LONG - 1);
340b1cb7e2bSHeiko Carstens }
341b1cb7e2bSHeiko Carstens 
342b1cb7e2bSHeiko Carstens /**
343b1cb7e2bSHeiko Carstens  * fls64 - find last set bit in a 64-bit word
344b1cb7e2bSHeiko Carstens  * @word: the word to search
345b1cb7e2bSHeiko Carstens  *
346b1cb7e2bSHeiko Carstens  * This is defined in a similar way as the libc and compiler builtin
347b1cb7e2bSHeiko Carstens  * ffsll, but returns the position of the most significant set bit.
348b1cb7e2bSHeiko Carstens  *
349b1cb7e2bSHeiko Carstens  * fls64(value) returns 0 if value is 0 or the position of the last
350b1cb7e2bSHeiko Carstens  * set bit if value is nonzero. The last (most significant) bit is
351b1cb7e2bSHeiko Carstens  * at position 64.
352b1cb7e2bSHeiko Carstens  */
fls64(unsigned long word)353b1cb7e2bSHeiko Carstens static inline int fls64(unsigned long word)
354b1cb7e2bSHeiko Carstens {
355b1cb7e2bSHeiko Carstens 	unsigned long mask = 2 * BITS_PER_LONG - 1;
356b1cb7e2bSHeiko Carstens 
357b1cb7e2bSHeiko Carstens 	return (1 + (__flogr(word) ^ (BITS_PER_LONG - 1))) & mask;
358b1cb7e2bSHeiko Carstens }
359b1cb7e2bSHeiko Carstens 
360b1cb7e2bSHeiko Carstens /**
361b1cb7e2bSHeiko Carstens  * fls - find last (most-significant) bit set
362b1cb7e2bSHeiko Carstens  * @word: the word to search
363b1cb7e2bSHeiko Carstens  *
364b1cb7e2bSHeiko Carstens  * This is defined the same way as ffs.
365b1cb7e2bSHeiko Carstens  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
366b1cb7e2bSHeiko Carstens  */
fls(unsigned int word)3673fc2579eSMatthew Wilcox static inline int fls(unsigned int word)
368b1cb7e2bSHeiko Carstens {
3693fc2579eSMatthew Wilcox 	return fls64(word);
370b1cb7e2bSHeiko Carstens }
371b1cb7e2bSHeiko Carstens 
372746479cdSHeiko Carstens #include <asm-generic/bitops/ffz.h>
373c6557e7fSMartin Schwidefsky #include <asm-generic/bitops/hweight.h>
374746479cdSHeiko Carstens #include <asm-generic/bitops/sched.h>
375802caabbSAkinobu Mita #include <asm-generic/bitops/le.h>
376148817baSAkinobu Mita #include <asm-generic/bitops/ext2-atomic-setbit.h>
37750b9b475SAkinobu Mita 
378c6557e7fSMartin Schwidefsky #endif /* _S390_BITOPS_H */
379