patch-1.3.94 linux/include/asm-m68k/bitops.h

Next file: linux/include/asm-m68k/bootinfo.h
Previous file: linux/include/asm-m68k/atomic.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.93/linux/include/asm-m68k/bitops.h linux/include/asm-m68k/bitops.h
@@ -11,10 +11,7 @@
 /*
  * 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).
+ * They use the standard big-endian m680x0 bit ordering.
  */
 
 extern __inline__ int set_bit(int nr,void * vaddr)
@@ -22,7 +19,7 @@
 	char retval;
 
 	__asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr), "a" (vaddr));
+	     : "=d" (retval) : "d" (nr^31), "a" (vaddr));
 
 	return retval;
 }
@@ -32,7 +29,7 @@
 	char retval;
 
 	__asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr), "a" (vaddr));
+	     : "=d" (retval) : "d" (nr^31), "a" (vaddr));
 
 	return retval;
 }
@@ -42,7 +39,7 @@
 	char retval;
 
 	__asm__ __volatile__ ("bfchg %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr), "a" (vaddr));
+	     : "=d" (retval) : "d" (nr^31), "a" (vaddr));
 
 	return retval;
 }
@@ -52,51 +49,52 @@
 	char retval;
 
 	__asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr), "a" (vaddr));
+	     : "=d" (retval) : "d" (nr^31), "a" (vaddr));
 
 	return retval;
 }
 
-extern inline int find_first_zero_bit(void * vaddr, unsigned size)
+extern __inline__ int find_first_zero_bit(void * vaddr, unsigned size)
 {
-	unsigned long res;
-	unsigned long *p;
-	unsigned long *addr = vaddr;
+	unsigned long *p = vaddr, *addr = vaddr;
+	unsigned long allones = ~0UL;
+	int res;
+	unsigned long num;
 
 	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;
+
+	while (*p++ == allones)
+	{
+		if (size <= 32)
+			return (p - addr) << 5;
+		size -= 32;
+	}
+
+	num = ~*--p;
+	__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
+			      : "=d" (res) : "d" (num & -num));
+	return ((p - addr) << 5) + (res ^ 31);
 }
 
-static inline int find_next_zero_bit (void *vaddr, int size,
+extern __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;
+	int set = 0, bit = offset & 31UL, res;
+
+	if (offset >= size)
+		return size;
 
 	if (bit) {
+		unsigned long num = ~*p & (~0UL << 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;
+		__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
+				      : "=d" (res) : "d" (num & -num));
+		if (res < 32)
+			return (offset & ~31UL) + (res ^ 31);
                 set = 32 - bit;
 		p++;
 	}
@@ -109,12 +107,151 @@
  * 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)
+extern __inline__ unsigned long ffz(unsigned long word)
 {
+	int res;
+
 	__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
-			      : "=d" (word)
-			      : "d" (~(word)));
-	return word;
+			      : "=d" (res) : "d" (~word & -~word));
+	return res ^ 31;
+}
+
+/* Bitmap functions for the minix filesystem */
+
+extern __inline__ int
+minix_find_first_zero_bit (const void *vaddr, unsigned size)
+{
+	const unsigned short *p = vaddr, *addr = vaddr;
+	int res;
+	unsigned short num;
+
+	if (!size)
+		return 0;
+
+	while (*p++ == 0xffff)
+	{
+		if (size <= 16)
+			return (p - addr) << 4;
+		size -= 16;
+	}
+
+	num = ~*--p;
+	__asm__ __volatile__ ("bfffo %1{#16,#16},%0"
+			      : "=d" (res) : "d" (num & -num));
+	return ((p - addr) << 4) + (res ^ 31);
+}
+
+extern __inline__ int
+minix_set_bit (int nr, void *vaddr)
+{
+	char retval;
+
+	__asm__ __volatile__ ("bfset %2{%1:#1}; sne %0"
+	     : "=d" (retval) : "d" (nr^15), "m" (*(char *)vaddr));
+
+	return retval;
+}
+
+extern __inline__ int
+minix_clear_bit (int nr, void *vaddr)
+{
+	char retval;
+
+	__asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0"
+	     : "=d" (retval) : "d" (nr^15), "m" (*(char *) vaddr));
+
+	return retval;
+}
+
+extern __inline__ int
+minix_test_bit (int nr, const void *vaddr)
+{
+	char retval;
+
+	__asm__ __volatile__ ("bftst %2{%1:#1}; sne %0"
+	     : "=d" (retval) : "d" (nr^15), "m" (*(const char *) vaddr));
+
+	return retval;
+}
+
+/* Bitmap functions for the ext2 filesystem. */
+
+extern __inline__ int
+ext2_set_bit (int nr, void *vaddr)
+{
+	char retval;
+
+	__asm__ __volatile__ ("bfset %2{%1,#1}; sne %0"
+	     : "=d" (retval) : "d" (nr^7), "m" (*(char *) vaddr));
+
+	return retval;
+}
+
+extern __inline__ int
+ext2_clear_bit (int nr, void *vaddr)
+{
+	char retval;
+
+	__asm__ __volatile__ ("bfclr %2{%1,#1}; sne %0"
+	     : "=d" (retval) : "d" (nr^7), "m" (*(char *) vaddr));
+
+	return retval;
+}
+
+extern __inline__ int
+ext2_test_bit (int nr, const void *vaddr)
+{
+	char retval;
+
+	__asm__ __volatile__ ("bftst %2{%1,#1}; sne %0"
+	     : "=d" (retval) : "d" (nr^7), "m" (*(const char *) vaddr));
+
+	return retval;
+}
+
+extern __inline__ int
+ext2_find_first_zero_bit (const void *vaddr, unsigned size)
+{
+	const unsigned long *p = vaddr, *addr = vaddr;
+	int res;
+
+	if (!size)
+		return 0;
+
+	while (*p++ == ~0UL)
+	{
+		if (size <= 32)
+			return (p - addr) << 5;
+		size -= 32;
+	}
+
+	--p;
+	for (res = 0; res < 32; res++)
+		if (!ext2_test_bit (res, p))
+			break;
+	return (p - addr) * 32 + res;
+}
+
+extern __inline__ int
+ext2_find_next_zero_bit (const void *vaddr, unsigned size, unsigned offset)
+{
+	const unsigned long *addr = vaddr;
+	const unsigned long *p = addr + (offset >> 5);
+	int bit = offset & 31UL, res;
+
+	if (offset >= size)
+		return size;
+
+	if (bit) {
+		/* Look for zero in first longword */
+		for (res = bit; res < 32; res++)
+			if (!ext2_test_bit (res, p))
+				return (p - addr) * 32 + res;
+		p++;
+	}
+	/* No zero yet, search remaining full bytes for a zero */
+	res = ext2_find_first_zero_bit (p, size - 32 * (p - addr));
+	return (p - addr) * 32 + res;
 }
 
 #endif /* _M68K_BITOPS_H */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this