blob: 529d0f2dbb81223aeec25187985dad04aef2d6c6 [file] [log] [blame]
Nobuhiro Iwamatsu547b67f2007-09-23 02:12:30 +09001#ifndef __ASM_SH_BITOPS_H
2#define __ASM_SH_BITOPS_H
Nobuhiro Iwamatsu970dc332007-05-13 20:58:00 +09003
Nobuhiro Iwamatsu547b67f2007-09-23 02:12:30 +09004#ifdef __KERNEL__
5//#include <asm/system.h>
6#include <asm/irqflags.h>
7/* For __swab32 */
8#include <asm/byteorder.h>
Nobuhiro Iwamatsu970dc332007-05-13 20:58:00 +09009
Nobuhiro Iwamatsu547b67f2007-09-23 02:12:30 +090010static inline void set_bit(int nr, volatile void * addr)
11{
12 int mask;
13 volatile unsigned int *a = addr;
14 unsigned long flags;
15
16 a += nr >> 5;
17 mask = 1 << (nr & 0x1f);
18 local_irq_save(flags);
19 *a |= mask;
20 local_irq_restore(flags);
21}
22
23/*
24 * clear_bit() doesn't provide any barrier for the compiler.
25 */
26#define smp_mb__before_clear_bit() barrier()
27#define smp_mb__after_clear_bit() barrier()
28static inline void clear_bit(int nr, volatile void * addr)
29{
30 int mask;
31 volatile unsigned int *a = addr;
32 unsigned long flags;
33
34 a += nr >> 5;
35 mask = 1 << (nr & 0x1f);
36 local_irq_save(flags);
37 *a &= ~mask;
38 local_irq_restore(flags);
39}
40
41static inline void change_bit(int nr, volatile void * addr)
42{
43 int mask;
44 volatile unsigned int *a = addr;
45 unsigned long flags;
46
47 a += nr >> 5;
48 mask = 1 << (nr & 0x1f);
49 local_irq_save(flags);
50 *a ^= mask;
51 local_irq_restore(flags);
52}
53
54static inline int test_and_set_bit(int nr, volatile void * addr)
55{
56 int mask, retval;
57 volatile unsigned int *a = addr;
58 unsigned long flags;
59
60 a += nr >> 5;
61 mask = 1 << (nr & 0x1f);
62 local_irq_save(flags);
63 retval = (mask & *a) != 0;
64 *a |= mask;
65 local_irq_restore(flags);
66
67 return retval;
68}
69
70static inline int test_and_clear_bit(int nr, volatile void * addr)
71{
72 int mask, retval;
73 volatile unsigned int *a = addr;
74 unsigned long flags;
75
76 a += nr >> 5;
77 mask = 1 << (nr & 0x1f);
78 local_irq_save(flags);
79 retval = (mask & *a) != 0;
80 *a &= ~mask;
81 local_irq_restore(flags);
82
83 return retval;
84}
85
86static inline int test_and_change_bit(int nr, volatile void * addr)
87{
88 int mask, retval;
89 volatile unsigned int *a = addr;
90 unsigned long flags;
91
92 a += nr >> 5;
93 mask = 1 << (nr & 0x1f);
94 local_irq_save(flags);
95 retval = (mask & *a) != 0;
96 *a ^= mask;
97 local_irq_restore(flags);
98
99 return retval;
100}
101
102//#include <asm-generic/bitops/non-atomic.h>
103
104static inline unsigned long ffz(unsigned long word)
105{
106 unsigned long result;
107
108 __asm__("1:\n\t"
109 "shlr %1\n\t"
110 "bt/s 1b\n\t"
111 " add #1, %0"
112 : "=r" (result), "=r" (word)
113 : "0" (~0L), "1" (word)
114 : "t");
115 return result;
116}
117
118/**
119 * ffs - find first bit in word.
120 * @word: The word to search
121 *
122 * Undefined if no bit exists, so code should check against 0 first.
123 */
124static inline int ffs(int x)
125{
126 int r = 1;
127
128 if (!x)
129 return 0;
130 if (!(x & 0xffff)) {
131 x >>= 16;
132 r += 16;
133 }
134 if (!(x & 0xff)) {
135 x >>= 8;
136 r += 8;
137 }
138 if (!(x & 0xf)) {
139 x >>= 4;
140 r += 4;
141 }
142 if (!(x & 3)) {
143 x >>= 2;
144 r += 2;
145 }
146 if (!(x & 1)) {
147 x >>= 1;
148 r += 1;
149 }
150 return r;
151}
152
153#if 0
154#include <asm-generic/bitops/find.h>
155#include <asm-generic/bitops/ffs.h>
156#include <asm-generic/bitops/hweight.h>
157#include <asm-generic/bitops/sched.h>
158#include <asm-generic/bitops/ext2-non-atomic.h>
159#include <asm-generic/bitops/ext2-atomic.h>
160#include <asm-generic/bitops/minix.h>
161#include <asm-generic/bitops/fls.h>
162#include <asm-generic/bitops/fls64.h>
Nobuhiro Iwamatsu970dc332007-05-13 20:58:00 +0900163#endif
Nobuhiro Iwamatsu547b67f2007-09-23 02:12:30 +0900164#endif /* __KERNEL__ */
165
166#endif /* __ASM_SH_BITOPS_H */