patch-2.4.11-dontuse linux/include/asm-cris/bitops.h
Next file: linux/include/asm-cris/checksum.h
Previous file: linux/include/asm-arm/processor.h
Back to the patch index
Back to the overall index
- Lines: 92
- Date:
Mon Oct 8 11:43:54 2001
- Orig file:
v2.4.10/linux/include/asm-cris/bitops.h
- Orig date:
Wed Jul 25 17:10:25 2001
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/bitops.h linux/include/asm-cris/bitops.h
@@ -19,6 +19,10 @@
#include <asm/system.h>
+/* We use generic_ffs so get it; include guards resolve the possible
+ mutually inclusion. */
+#include <linux/bitops.h>
+
/*
* Some hacks to defeat gcc over-optimizations..
*/
@@ -215,33 +219,62 @@
*/
/*
+ * Helper functions for the core of the ff[sz] functions, wrapping the
+ * syntactically awkward asms. The asms compute the number of leading
+ * zeroes of a bits-in-byte and byte-in-word and word-in-dword-swapped
+ * number. They differ in that the first function also inverts all bits
+ * in the input.
+ */
+static __inline__ unsigned long cris_swapnwbrlz(unsigned long w)
+{
+ /* Let's just say we return the result in the same register as the
+ input. Saying we clobber the input but can return the result
+ in another register:
+ ! __asm__ ("swapnwbr %2\n\tlz %2,%0"
+ ! : "=r,r" (res), "=r,X" (dummy) : "1,0" (w));
+ confuses gcc (sched.c, gcc from cris-dist-1.14). */
+
+ unsigned long res;
+ __asm__ ("swapnwbr %0 \n\t"
+ "lz %0,%0"
+ : "=r" (res) : "0" (w));
+ return res;
+}
+
+static __inline__ unsigned long cris_swapwbrlz(unsigned long w)
+{
+ unsigned res;
+ __asm__ ("swapwbr %0 \n\t"
+ "lz %0,%0"
+ : "=r" (res)
+ : "0" (w));
+ return res;
+}
+
+/*
* ffz = Find First Zero in word. Undefined if no zero exists,
* so code should check against ~0UL first..
*/
-static __inline__ unsigned long ffz(unsigned long word)
+static __inline__ unsigned long ffz(unsigned long w)
{
- unsigned long result = 0;
-
- while(word & 1) {
- result++;
- word >>= 1;
- }
- return result;
+ /* The generic_ffs function is used to avoid the asm when the
+ argument is a constant. */
+ return __builtin_constant_p (w)
+ ? (~w ? (unsigned long) generic_ffs ((int) ~w) - 1 : 32)
+ : cris_swapnwbrlz (w);
}
/*
- * Find first one in word. Undefined if no one exists,
- * so code should check against 0UL first..
+ * Somewhat like ffz but the equivalent of generic_ffs: in contrast to
+ * ffz we return the first one-bit *plus one*.
*/
-static __inline__ unsigned long find_first_one(unsigned long word)
+static __inline__ unsigned long ffs(unsigned long w)
{
- unsigned long result = 0;
-
- while(!(word & 1)) {
- result++;
- word >>= 1;
- }
- return result;
+ /* The generic_ffs function is used to avoid the asm when the
+ argument is a constant. */
+ return __builtin_constant_p (w)
+ ? (unsigned long) generic_ffs ((int) w)
+ : w ? cris_swapwbrlz (w) + 1 : 0;
}
/**
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)