162306a36Sopenharmony_ci#ifndef _M68K_BITOPS_H
262306a36Sopenharmony_ci#define _M68K_BITOPS_H
362306a36Sopenharmony_ci/*
462306a36Sopenharmony_ci * Copyright 1992, Linus Torvalds.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
762306a36Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
862306a36Sopenharmony_ci * for more details.
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef _LINUX_BITOPS_H
1262306a36Sopenharmony_ci#error only <linux/bitops.h> can be included directly
1362306a36Sopenharmony_ci#endif
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/compiler.h>
1662306a36Sopenharmony_ci#include <asm/barrier.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/*
1962306a36Sopenharmony_ci *	Bit access functions vary across the ColdFire and 68k families.
2062306a36Sopenharmony_ci *	So we will break them out here, and then macro in the ones we want.
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci *	ColdFire - supports standard bset/bclr/bchg with register operand only
2362306a36Sopenharmony_ci *	68000    - supports standard bset/bclr/bchg with memory operand
2462306a36Sopenharmony_ci *	>= 68020 - also supports the bfset/bfclr/bfchg instructions
2562306a36Sopenharmony_ci *
2662306a36Sopenharmony_ci *	Although it is possible to use only the bset/bclr/bchg with register
2762306a36Sopenharmony_ci *	operands on all platforms you end up with larger generated code.
2862306a36Sopenharmony_ci *	So we use the best form possible on a given platform.
2962306a36Sopenharmony_ci */
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistatic inline void bset_reg_set_bit(int nr, volatile unsigned long *vaddr)
3262306a36Sopenharmony_ci{
3362306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	__asm__ __volatile__ ("bset %1,(%0)"
3662306a36Sopenharmony_ci		:
3762306a36Sopenharmony_ci		: "a" (p), "di" (nr & 7)
3862306a36Sopenharmony_ci		: "memory");
3962306a36Sopenharmony_ci}
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistatic inline void bset_mem_set_bit(int nr, volatile unsigned long *vaddr)
4262306a36Sopenharmony_ci{
4362306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	__asm__ __volatile__ ("bset %1,%0"
4662306a36Sopenharmony_ci		: "+m" (*p)
4762306a36Sopenharmony_ci		: "di" (nr & 7));
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic inline void bfset_mem_set_bit(int nr, volatile unsigned long *vaddr)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	__asm__ __volatile__ ("bfset %1{%0:#1}"
5362306a36Sopenharmony_ci		:
5462306a36Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
5562306a36Sopenharmony_ci		: "memory");
5662306a36Sopenharmony_ci}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
5962306a36Sopenharmony_ci#define	set_bit(nr, vaddr)	bset_reg_set_bit(nr, vaddr)
6062306a36Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
6162306a36Sopenharmony_ci#define	set_bit(nr, vaddr)	bset_mem_set_bit(nr, vaddr)
6262306a36Sopenharmony_ci#else
6362306a36Sopenharmony_ci#define set_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
6462306a36Sopenharmony_ci				bset_mem_set_bit(nr, vaddr) : \
6562306a36Sopenharmony_ci				bfset_mem_set_bit(nr, vaddr))
6662306a36Sopenharmony_ci#endif
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_cistatic __always_inline void
6962306a36Sopenharmony_ciarch___set_bit(unsigned long nr, volatile unsigned long *addr)
7062306a36Sopenharmony_ci{
7162306a36Sopenharmony_ci	set_bit(nr, addr);
7262306a36Sopenharmony_ci}
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistatic inline void bclr_reg_clear_bit(int nr, volatile unsigned long *vaddr)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	__asm__ __volatile__ ("bclr %1,(%0)"
7962306a36Sopenharmony_ci		:
8062306a36Sopenharmony_ci		: "a" (p), "di" (nr & 7)
8162306a36Sopenharmony_ci		: "memory");
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_cistatic inline void bclr_mem_clear_bit(int nr, volatile unsigned long *vaddr)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	__asm__ __volatile__ ("bclr %1,%0"
8962306a36Sopenharmony_ci		: "+m" (*p)
9062306a36Sopenharmony_ci		: "di" (nr & 7));
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic inline void bfclr_mem_clear_bit(int nr, volatile unsigned long *vaddr)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	__asm__ __volatile__ ("bfclr %1{%0:#1}"
9662306a36Sopenharmony_ci		:
9762306a36Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
9862306a36Sopenharmony_ci		: "memory");
9962306a36Sopenharmony_ci}
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
10262306a36Sopenharmony_ci#define	clear_bit(nr, vaddr)	bclr_reg_clear_bit(nr, vaddr)
10362306a36Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
10462306a36Sopenharmony_ci#define	clear_bit(nr, vaddr)	bclr_mem_clear_bit(nr, vaddr)
10562306a36Sopenharmony_ci#else
10662306a36Sopenharmony_ci#define clear_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
10762306a36Sopenharmony_ci				bclr_mem_clear_bit(nr, vaddr) : \
10862306a36Sopenharmony_ci				bfclr_mem_clear_bit(nr, vaddr))
10962306a36Sopenharmony_ci#endif
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cistatic __always_inline void
11262306a36Sopenharmony_ciarch___clear_bit(unsigned long nr, volatile unsigned long *addr)
11362306a36Sopenharmony_ci{
11462306a36Sopenharmony_ci	clear_bit(nr, addr);
11562306a36Sopenharmony_ci}
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic inline void bchg_reg_change_bit(int nr, volatile unsigned long *vaddr)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	__asm__ __volatile__ ("bchg %1,(%0)"
12262306a36Sopenharmony_ci		:
12362306a36Sopenharmony_ci		: "a" (p), "di" (nr & 7)
12462306a36Sopenharmony_ci		: "memory");
12562306a36Sopenharmony_ci}
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cistatic inline void bchg_mem_change_bit(int nr, volatile unsigned long *vaddr)
12862306a36Sopenharmony_ci{
12962306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	__asm__ __volatile__ ("bchg %1,%0"
13262306a36Sopenharmony_ci		: "+m" (*p)
13362306a36Sopenharmony_ci		: "di" (nr & 7));
13462306a36Sopenharmony_ci}
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistatic inline void bfchg_mem_change_bit(int nr, volatile unsigned long *vaddr)
13762306a36Sopenharmony_ci{
13862306a36Sopenharmony_ci	__asm__ __volatile__ ("bfchg %1{%0:#1}"
13962306a36Sopenharmony_ci		:
14062306a36Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
14162306a36Sopenharmony_ci		: "memory");
14262306a36Sopenharmony_ci}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
14562306a36Sopenharmony_ci#define	change_bit(nr, vaddr)	bchg_reg_change_bit(nr, vaddr)
14662306a36Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
14762306a36Sopenharmony_ci#define	change_bit(nr, vaddr)	bchg_mem_change_bit(nr, vaddr)
14862306a36Sopenharmony_ci#else
14962306a36Sopenharmony_ci#define change_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
15062306a36Sopenharmony_ci				bchg_mem_change_bit(nr, vaddr) : \
15162306a36Sopenharmony_ci				bfchg_mem_change_bit(nr, vaddr))
15262306a36Sopenharmony_ci#endif
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_cistatic __always_inline void
15562306a36Sopenharmony_ciarch___change_bit(unsigned long nr, volatile unsigned long *addr)
15662306a36Sopenharmony_ci{
15762306a36Sopenharmony_ci	change_bit(nr, addr);
15862306a36Sopenharmony_ci}
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci#define arch_test_bit generic_test_bit
16162306a36Sopenharmony_ci#define arch_test_bit_acquire generic_test_bit_acquire
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistatic inline int bset_reg_test_and_set_bit(int nr,
16462306a36Sopenharmony_ci					    volatile unsigned long *vaddr)
16562306a36Sopenharmony_ci{
16662306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
16762306a36Sopenharmony_ci	char retval;
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	__asm__ __volatile__ ("bset %2,(%1); sne %0"
17062306a36Sopenharmony_ci		: "=d" (retval)
17162306a36Sopenharmony_ci		: "a" (p), "di" (nr & 7)
17262306a36Sopenharmony_ci		: "memory");
17362306a36Sopenharmony_ci	return retval;
17462306a36Sopenharmony_ci}
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_cistatic inline int bset_mem_test_and_set_bit(int nr,
17762306a36Sopenharmony_ci					    volatile unsigned long *vaddr)
17862306a36Sopenharmony_ci{
17962306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
18062306a36Sopenharmony_ci	char retval;
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	__asm__ __volatile__ ("bset %2,%1; sne %0"
18362306a36Sopenharmony_ci		: "=d" (retval), "+m" (*p)
18462306a36Sopenharmony_ci		: "di" (nr & 7));
18562306a36Sopenharmony_ci	return retval;
18662306a36Sopenharmony_ci}
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_cistatic inline int bfset_mem_test_and_set_bit(int nr,
18962306a36Sopenharmony_ci					     volatile unsigned long *vaddr)
19062306a36Sopenharmony_ci{
19162306a36Sopenharmony_ci	char retval;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	__asm__ __volatile__ ("bfset %2{%1:#1}; sne %0"
19462306a36Sopenharmony_ci		: "=d" (retval)
19562306a36Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
19662306a36Sopenharmony_ci		: "memory");
19762306a36Sopenharmony_ci	return retval;
19862306a36Sopenharmony_ci}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
20162306a36Sopenharmony_ci#define	test_and_set_bit(nr, vaddr)	bset_reg_test_and_set_bit(nr, vaddr)
20262306a36Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
20362306a36Sopenharmony_ci#define	test_and_set_bit(nr, vaddr)	bset_mem_test_and_set_bit(nr, vaddr)
20462306a36Sopenharmony_ci#else
20562306a36Sopenharmony_ci#define test_and_set_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
20662306a36Sopenharmony_ci					bset_mem_test_and_set_bit(nr, vaddr) : \
20762306a36Sopenharmony_ci					bfset_mem_test_and_set_bit(nr, vaddr))
20862306a36Sopenharmony_ci#endif
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_cistatic __always_inline bool
21162306a36Sopenharmony_ciarch___test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	return test_and_set_bit(nr, addr);
21462306a36Sopenharmony_ci}
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_cistatic inline int bclr_reg_test_and_clear_bit(int nr,
21762306a36Sopenharmony_ci					      volatile unsigned long *vaddr)
21862306a36Sopenharmony_ci{
21962306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
22062306a36Sopenharmony_ci	char retval;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	__asm__ __volatile__ ("bclr %2,(%1); sne %0"
22362306a36Sopenharmony_ci		: "=d" (retval)
22462306a36Sopenharmony_ci		: "a" (p), "di" (nr & 7)
22562306a36Sopenharmony_ci		: "memory");
22662306a36Sopenharmony_ci	return retval;
22762306a36Sopenharmony_ci}
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_cistatic inline int bclr_mem_test_and_clear_bit(int nr,
23062306a36Sopenharmony_ci					      volatile unsigned long *vaddr)
23162306a36Sopenharmony_ci{
23262306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
23362306a36Sopenharmony_ci	char retval;
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	__asm__ __volatile__ ("bclr %2,%1; sne %0"
23662306a36Sopenharmony_ci		: "=d" (retval), "+m" (*p)
23762306a36Sopenharmony_ci		: "di" (nr & 7));
23862306a36Sopenharmony_ci	return retval;
23962306a36Sopenharmony_ci}
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_cistatic inline int bfclr_mem_test_and_clear_bit(int nr,
24262306a36Sopenharmony_ci					       volatile unsigned long *vaddr)
24362306a36Sopenharmony_ci{
24462306a36Sopenharmony_ci	char retval;
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci	__asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0"
24762306a36Sopenharmony_ci		: "=d" (retval)
24862306a36Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
24962306a36Sopenharmony_ci		: "memory");
25062306a36Sopenharmony_ci	return retval;
25162306a36Sopenharmony_ci}
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
25462306a36Sopenharmony_ci#define	test_and_clear_bit(nr, vaddr)	bclr_reg_test_and_clear_bit(nr, vaddr)
25562306a36Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
25662306a36Sopenharmony_ci#define	test_and_clear_bit(nr, vaddr)	bclr_mem_test_and_clear_bit(nr, vaddr)
25762306a36Sopenharmony_ci#else
25862306a36Sopenharmony_ci#define test_and_clear_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
25962306a36Sopenharmony_ci					bclr_mem_test_and_clear_bit(nr, vaddr) : \
26062306a36Sopenharmony_ci					bfclr_mem_test_and_clear_bit(nr, vaddr))
26162306a36Sopenharmony_ci#endif
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_cistatic __always_inline bool
26462306a36Sopenharmony_ciarch___test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
26562306a36Sopenharmony_ci{
26662306a36Sopenharmony_ci	return test_and_clear_bit(nr, addr);
26762306a36Sopenharmony_ci}
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_cistatic inline int bchg_reg_test_and_change_bit(int nr,
27062306a36Sopenharmony_ci					       volatile unsigned long *vaddr)
27162306a36Sopenharmony_ci{
27262306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
27362306a36Sopenharmony_ci	char retval;
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	__asm__ __volatile__ ("bchg %2,(%1); sne %0"
27662306a36Sopenharmony_ci		: "=d" (retval)
27762306a36Sopenharmony_ci		: "a" (p), "di" (nr & 7)
27862306a36Sopenharmony_ci		: "memory");
27962306a36Sopenharmony_ci	return retval;
28062306a36Sopenharmony_ci}
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_cistatic inline int bchg_mem_test_and_change_bit(int nr,
28362306a36Sopenharmony_ci					       volatile unsigned long *vaddr)
28462306a36Sopenharmony_ci{
28562306a36Sopenharmony_ci	char *p = (char *)vaddr + (nr ^ 31) / 8;
28662306a36Sopenharmony_ci	char retval;
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	__asm__ __volatile__ ("bchg %2,%1; sne %0"
28962306a36Sopenharmony_ci		: "=d" (retval), "+m" (*p)
29062306a36Sopenharmony_ci		: "di" (nr & 7));
29162306a36Sopenharmony_ci	return retval;
29262306a36Sopenharmony_ci}
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_cistatic inline int bfchg_mem_test_and_change_bit(int nr,
29562306a36Sopenharmony_ci						volatile unsigned long *vaddr)
29662306a36Sopenharmony_ci{
29762306a36Sopenharmony_ci	char retval;
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	__asm__ __volatile__ ("bfchg %2{%1:#1}; sne %0"
30062306a36Sopenharmony_ci		: "=d" (retval)
30162306a36Sopenharmony_ci		: "d" (nr ^ 31), "o" (*vaddr)
30262306a36Sopenharmony_ci		: "memory");
30362306a36Sopenharmony_ci	return retval;
30462306a36Sopenharmony_ci}
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci#if defined(CONFIG_COLDFIRE)
30762306a36Sopenharmony_ci#define	test_and_change_bit(nr, vaddr)	bchg_reg_test_and_change_bit(nr, vaddr)
30862306a36Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
30962306a36Sopenharmony_ci#define	test_and_change_bit(nr, vaddr)	bchg_mem_test_and_change_bit(nr, vaddr)
31062306a36Sopenharmony_ci#else
31162306a36Sopenharmony_ci#define test_and_change_bit(nr, vaddr)	(__builtin_constant_p(nr) ? \
31262306a36Sopenharmony_ci					bchg_mem_test_and_change_bit(nr, vaddr) : \
31362306a36Sopenharmony_ci					bfchg_mem_test_and_change_bit(nr, vaddr))
31462306a36Sopenharmony_ci#endif
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_cistatic __always_inline bool
31762306a36Sopenharmony_ciarch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
31862306a36Sopenharmony_ci{
31962306a36Sopenharmony_ci	return test_and_change_bit(nr, addr);
32062306a36Sopenharmony_ci}
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci/*
32362306a36Sopenharmony_ci *	The true 68020 and more advanced processors support the "bfffo"
32462306a36Sopenharmony_ci *	instruction for finding bits. ColdFire and simple 68000 parts
32562306a36Sopenharmony_ci *	(including CPU32) do not support this. They simply use the generic
32662306a36Sopenharmony_ci *	functions.
32762306a36Sopenharmony_ci */
32862306a36Sopenharmony_ci#if defined(CONFIG_CPU_HAS_NO_BITFIELDS)
32962306a36Sopenharmony_ci#include <asm-generic/bitops/ffz.h>
33062306a36Sopenharmony_ci#else
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_cistatic inline int find_first_zero_bit(const unsigned long *vaddr,
33362306a36Sopenharmony_ci				      unsigned size)
33462306a36Sopenharmony_ci{
33562306a36Sopenharmony_ci	const unsigned long *p = vaddr;
33662306a36Sopenharmony_ci	int res = 32;
33762306a36Sopenharmony_ci	unsigned int words;
33862306a36Sopenharmony_ci	unsigned long num;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	if (!size)
34162306a36Sopenharmony_ci		return 0;
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	words = (size + 31) >> 5;
34462306a36Sopenharmony_ci	while (!(num = ~*p++)) {
34562306a36Sopenharmony_ci		if (!--words)
34662306a36Sopenharmony_ci			goto out;
34762306a36Sopenharmony_ci	}
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
35062306a36Sopenharmony_ci			      : "=d" (res) : "d" (num & -num));
35162306a36Sopenharmony_ci	res ^= 31;
35262306a36Sopenharmony_ciout:
35362306a36Sopenharmony_ci	res += ((long)p - (long)vaddr - 4) * 8;
35462306a36Sopenharmony_ci	return res < size ? res : size;
35562306a36Sopenharmony_ci}
35662306a36Sopenharmony_ci#define find_first_zero_bit find_first_zero_bit
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_cistatic inline int find_next_zero_bit(const unsigned long *vaddr, int size,
35962306a36Sopenharmony_ci				     int offset)
36062306a36Sopenharmony_ci{
36162306a36Sopenharmony_ci	const unsigned long *p = vaddr + (offset >> 5);
36262306a36Sopenharmony_ci	int bit = offset & 31UL, res;
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	if (offset >= size)
36562306a36Sopenharmony_ci		return size;
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	if (bit) {
36862306a36Sopenharmony_ci		unsigned long num = ~*p++ & (~0UL << bit);
36962306a36Sopenharmony_ci		offset -= bit;
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci		/* Look for zero in first longword */
37262306a36Sopenharmony_ci		__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
37362306a36Sopenharmony_ci				      : "=d" (res) : "d" (num & -num));
37462306a36Sopenharmony_ci		if (res < 32) {
37562306a36Sopenharmony_ci			offset += res ^ 31;
37662306a36Sopenharmony_ci			return offset < size ? offset : size;
37762306a36Sopenharmony_ci		}
37862306a36Sopenharmony_ci		offset += 32;
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci		if (offset >= size)
38162306a36Sopenharmony_ci			return size;
38262306a36Sopenharmony_ci	}
38362306a36Sopenharmony_ci	/* No zero yet, search remaining full bytes for a zero */
38462306a36Sopenharmony_ci	return offset + find_first_zero_bit(p, size - offset);
38562306a36Sopenharmony_ci}
38662306a36Sopenharmony_ci#define find_next_zero_bit find_next_zero_bit
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_cistatic inline int find_first_bit(const unsigned long *vaddr, unsigned size)
38962306a36Sopenharmony_ci{
39062306a36Sopenharmony_ci	const unsigned long *p = vaddr;
39162306a36Sopenharmony_ci	int res = 32;
39262306a36Sopenharmony_ci	unsigned int words;
39362306a36Sopenharmony_ci	unsigned long num;
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci	if (!size)
39662306a36Sopenharmony_ci		return 0;
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	words = (size + 31) >> 5;
39962306a36Sopenharmony_ci	while (!(num = *p++)) {
40062306a36Sopenharmony_ci		if (!--words)
40162306a36Sopenharmony_ci			goto out;
40262306a36Sopenharmony_ci	}
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
40562306a36Sopenharmony_ci			      : "=d" (res) : "d" (num & -num));
40662306a36Sopenharmony_ci	res ^= 31;
40762306a36Sopenharmony_ciout:
40862306a36Sopenharmony_ci	res += ((long)p - (long)vaddr - 4) * 8;
40962306a36Sopenharmony_ci	return res < size ? res : size;
41062306a36Sopenharmony_ci}
41162306a36Sopenharmony_ci#define find_first_bit find_first_bit
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_cistatic inline int find_next_bit(const unsigned long *vaddr, int size,
41462306a36Sopenharmony_ci				int offset)
41562306a36Sopenharmony_ci{
41662306a36Sopenharmony_ci	const unsigned long *p = vaddr + (offset >> 5);
41762306a36Sopenharmony_ci	int bit = offset & 31UL, res;
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci	if (offset >= size)
42062306a36Sopenharmony_ci		return size;
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	if (bit) {
42362306a36Sopenharmony_ci		unsigned long num = *p++ & (~0UL << bit);
42462306a36Sopenharmony_ci		offset -= bit;
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci		/* Look for one in first longword */
42762306a36Sopenharmony_ci		__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
42862306a36Sopenharmony_ci				      : "=d" (res) : "d" (num & -num));
42962306a36Sopenharmony_ci		if (res < 32) {
43062306a36Sopenharmony_ci			offset += res ^ 31;
43162306a36Sopenharmony_ci			return offset < size ? offset : size;
43262306a36Sopenharmony_ci		}
43362306a36Sopenharmony_ci		offset += 32;
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ci		if (offset >= size)
43662306a36Sopenharmony_ci			return size;
43762306a36Sopenharmony_ci	}
43862306a36Sopenharmony_ci	/* No one yet, search remaining full bytes for a one */
43962306a36Sopenharmony_ci	return offset + find_first_bit(p, size - offset);
44062306a36Sopenharmony_ci}
44162306a36Sopenharmony_ci#define find_next_bit find_next_bit
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci/*
44462306a36Sopenharmony_ci * ffz = Find First Zero in word. Undefined if no zero exists,
44562306a36Sopenharmony_ci * so code should check against ~0UL first..
44662306a36Sopenharmony_ci */
44762306a36Sopenharmony_cistatic inline unsigned long ffz(unsigned long word)
44862306a36Sopenharmony_ci{
44962306a36Sopenharmony_ci	int res;
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci	__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
45262306a36Sopenharmony_ci			      : "=d" (res) : "d" (~word & -~word));
45362306a36Sopenharmony_ci	return res ^ 31;
45462306a36Sopenharmony_ci}
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci#endif
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci#ifdef __KERNEL__
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci#if defined(CONFIG_CPU_HAS_NO_BITFIELDS)
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci/*
46362306a36Sopenharmony_ci *	The newer ColdFire family members support a "bitrev" instruction
46462306a36Sopenharmony_ci *	and we can use that to implement a fast ffs. Older Coldfire parts,
46562306a36Sopenharmony_ci *	and normal 68000 parts don't have anything special, so we use the
46662306a36Sopenharmony_ci *	generic functions for those.
46762306a36Sopenharmony_ci */
46862306a36Sopenharmony_ci#if (defined(__mcfisaaplus__) || defined(__mcfisac__)) && \
46962306a36Sopenharmony_ci	!defined(CONFIG_M68000)
47062306a36Sopenharmony_cistatic inline unsigned long __ffs(unsigned long x)
47162306a36Sopenharmony_ci{
47262306a36Sopenharmony_ci	__asm__ __volatile__ ("bitrev %0; ff1 %0"
47362306a36Sopenharmony_ci		: "=d" (x)
47462306a36Sopenharmony_ci		: "0" (x));
47562306a36Sopenharmony_ci	return x;
47662306a36Sopenharmony_ci}
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_cistatic inline int ffs(int x)
47962306a36Sopenharmony_ci{
48062306a36Sopenharmony_ci	if (!x)
48162306a36Sopenharmony_ci		return 0;
48262306a36Sopenharmony_ci	return __ffs(x) + 1;
48362306a36Sopenharmony_ci}
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci#else
48662306a36Sopenharmony_ci#include <asm-generic/bitops/ffs.h>
48762306a36Sopenharmony_ci#include <asm-generic/bitops/__ffs.h>
48862306a36Sopenharmony_ci#endif
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci#include <asm-generic/bitops/fls.h>
49162306a36Sopenharmony_ci#include <asm-generic/bitops/__fls.h>
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci#else
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci/*
49662306a36Sopenharmony_ci *	ffs: find first bit set. This is defined the same way as
49762306a36Sopenharmony_ci *	the libc and compiler builtin ffs routines, therefore
49862306a36Sopenharmony_ci *	differs in spirit from the above ffz (man ffs).
49962306a36Sopenharmony_ci */
50062306a36Sopenharmony_cistatic inline int ffs(int x)
50162306a36Sopenharmony_ci{
50262306a36Sopenharmony_ci	int cnt;
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_ci	__asm__ ("bfffo %1{#0:#0},%0"
50562306a36Sopenharmony_ci		: "=d" (cnt)
50662306a36Sopenharmony_ci		: "dm" (x & -x));
50762306a36Sopenharmony_ci	return 32 - cnt;
50862306a36Sopenharmony_ci}
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_cistatic inline unsigned long __ffs(unsigned long x)
51162306a36Sopenharmony_ci{
51262306a36Sopenharmony_ci	return ffs(x) - 1;
51362306a36Sopenharmony_ci}
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci/*
51662306a36Sopenharmony_ci *	fls: find last bit set.
51762306a36Sopenharmony_ci */
51862306a36Sopenharmony_cistatic inline int fls(unsigned int x)
51962306a36Sopenharmony_ci{
52062306a36Sopenharmony_ci	int cnt;
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	__asm__ ("bfffo %1{#0,#0},%0"
52362306a36Sopenharmony_ci		: "=d" (cnt)
52462306a36Sopenharmony_ci		: "dm" (x));
52562306a36Sopenharmony_ci	return 32 - cnt;
52662306a36Sopenharmony_ci}
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_cistatic inline unsigned long __fls(unsigned long x)
52962306a36Sopenharmony_ci{
53062306a36Sopenharmony_ci	return fls(x) - 1;
53162306a36Sopenharmony_ci}
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci#endif
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci/* Simple test-and-set bit locks */
53662306a36Sopenharmony_ci#define test_and_set_bit_lock	test_and_set_bit
53762306a36Sopenharmony_ci#define clear_bit_unlock	clear_bit
53862306a36Sopenharmony_ci#define __clear_bit_unlock	clear_bit_unlock
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci#include <asm-generic/bitops/non-instrumented-non-atomic.h>
54162306a36Sopenharmony_ci#include <asm-generic/bitops/ext2-atomic.h>
54262306a36Sopenharmony_ci#include <asm-generic/bitops/fls64.h>
54362306a36Sopenharmony_ci#include <asm-generic/bitops/sched.h>
54462306a36Sopenharmony_ci#include <asm-generic/bitops/hweight.h>
54562306a36Sopenharmony_ci#include <asm-generic/bitops/le.h>
54662306a36Sopenharmony_ci#endif /* __KERNEL__ */
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci#endif /* _M68K_BITOPS_H */
549