summaryrefslogtreecommitdiffstats
path: root/include/asm-m68k/bitops.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-m68k/bitops.h')
-rw-r--r--include/asm-m68k/bitops.h120
1 files changed, 120 insertions, 0 deletions
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h
new file mode 100644
index 000000000..901fa48a0
--- /dev/null
+++ b/include/asm-m68k/bitops.h
@@ -0,0 +1,120 @@
+#ifndef _M68K_BITOPS_H
+#define _M68K_BITOPS_H
+/*
+ * Copyright 1992, Linus Torvalds.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * Require 68020 or better.
+ *
+ * They don't use the standard m680x0 bit ordering.
+ * Instead, the use the standard m680x0 bitfield ordering.
+ *
+ * Thus, bit 0 is the MSB of addr; bit 32 is the MSB of (addr+1).
+ */
+
+extern __inline__ int set_bit(int nr,void * vaddr)
+{
+ char retval;
+
+ __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
+ : "=d" (retval) : "d" (nr), "a" (vaddr));
+
+ return retval;
+}
+
+extern __inline__ int clear_bit(int nr, void * vaddr)
+{
+ char retval;
+
+ __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
+ : "=d" (retval) : "d" (nr), "a" (vaddr));
+
+ return retval;
+}
+
+extern __inline__ int change_bit(int nr, void * vaddr)
+{
+ char retval;
+
+ __asm__ __volatile__ ("bfchg %2@{%1:#1}; sne %0"
+ : "=d" (retval) : "d" (nr), "a" (vaddr));
+
+ return retval;
+}
+
+extern __inline__ int test_bit(int nr, const void * vaddr)
+{
+ char retval;
+
+ __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
+ : "=d" (retval) : "d" (nr), "a" (vaddr));
+
+ return retval;
+}
+
+extern inline int find_first_zero_bit(void * vaddr, unsigned size)
+{
+ unsigned long res;
+ unsigned long *p;
+ unsigned long *addr = vaddr;
+
+ if (!size)
+ return 0;
+ __asm__ __volatile__ (" moveq #-1,d0\n\t"
+ "1:"
+ " cmpl %1@+,d0\n\t"
+ " bne 2f\n\t"
+ " subql #1,%0\n\t"
+ " bne 1b\n\t"
+ " bra 5f\n\t"
+ "2:"
+ " movel %1@-,d0\n\t"
+ " notl d0\n\t"
+ " bfffo d0{#0,#0},%0\n\t"
+ "5:"
+ : "=d" (res), "=a" (p)
+ : "0" ((size + 31) >> 5), "1" (addr)
+ : "d0");
+ return ((p - addr) << 5) + res;
+}
+
+static inline int find_next_zero_bit (void *vaddr, int size,
+ int offset)
+{
+ unsigned long *addr = vaddr;
+ unsigned long *p = addr + (offset >> 5);
+ int set = 0, bit = offset & 31, res;
+
+ if (bit) {
+ /* Look for zero in first longword */
+ __asm__("bfffo %1{#0,#0},%0"
+ : "=d" (set)
+ : "d" (~*p << bit));
+ if (set < (32 - bit))
+ return set + offset;
+ set = 32 - bit;
+ p++;
+ }
+ /* No zero yet, search remaining full bytes for a zero */
+ res = find_first_zero_bit (p, size - 32 * (p - addr));
+ return (offset + set + res);
+}
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+extern inline unsigned long ffz(unsigned long word)
+{
+ __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
+ : "=d" (word)
+ : "d" (~(word)));
+ return word;
+}
+
+#endif /* _M68K_BITOPS_H */