[parisc-linux-cvs] Re: 2.6.0-test4-pa12 __fls()

Grant Grundler grundler@parisc-linux.org
Fri, 5 Sep 2003 23:59:14 -0600


On Fri, Sep 05, 2003 at 11:53:26PM -0600, Grant Grundler wrote:
> Log message:
> 2.6.0-test4-pa12 PARISC __fls()
> 
> Original:
> http://lists.parisc-linux.org/pipermail/parisc-linux/2003-August/020628.html
> 
> kudos to Joel Soete for mangling lamont's __ffs() to produce __fls().
> Again, I added 64-bit support.  Booted on a500.
> Didn't test 32-bit but fls_test.c included in above URL works in user space.
> (162 cycles per loop iteration, 00:29:01 to complete on 400Mhz PA8500).

DIFF appended.

grant

Index: Makefile
===================================================================
RCS file: /var/cvs/linux-2.6/Makefile,v
retrieving revision 1.31
diff -u -p -r1.31 Makefile
--- Makefile	5 Sep 2003 19:11:23 -0000	1.31
+++ Makefile	6 Sep 2003 05:36:44 -0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 0
-EXTRAVERSION = -test4-pa11
+EXTRAVERSION = -test4-pa12
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
Index: include/asm-parisc/bitops.h
===================================================================
RCS file: /var/cvs/linux-2.6/include/asm-parisc/bitops.h,v
retrieving revision 1.2
diff -u -p -r1.2 bitops.h
--- include/asm-parisc/bitops.h	1 Sep 2003 00:30:42 -0000	1.2
+++ include/asm-parisc/bitops.h	6 Sep 2003 05:36:47 -0000
@@ -264,7 +264,7 @@ static __inline__ unsigned long __ffs(un
 		" addi    -2,%1,%1\n"
 		" extru,=  %0,31,1,%%r0\n"
 		" addi    -1,%1,%1\n"
-		: "+r" (x), "=r" (ret) );
+			: "+r" (x), "=r" (ret) );
 	return ret;
 }
 
@@ -275,15 +275,46 @@ static __inline__ unsigned long __ffs(un
  */
 static __inline__ int ffs(int x)
 {
-	if (!x) return 0;
-	return __ffs((unsigned long)x) + 1;
+	return x ? (__ffs((unsigned long)x) + 1) : 0;
 }
 
 /*
- * fls: find last bit set.
+ * fls: find last (most significant) bit set.
  */
 
-#define fls(x) generic_fls(x)
+static __inline__ unsigned long __fls(unsigned long x)
+{
+	unsigned long ret;
+
+	__asm__( " ldi    1,%1\n"
+#if BITS_PER_LONG > 32
+		" extrd,u,*<>  %0,63,32,%%r0\n"
+		" depd,*TR  %0,31,32,%0\n"
+		" addi    32,%1,%1\n"
+#endif
+		" extru,<>  %0,15,16,%%r0\n"
+		" zdep,TR  %0,15,16,%0\n"
+		" addi     16,%1,%1\n"
+		" extru,<>  %0,7,8,%%r19\n"
+		" zdep,TR  %0,23,24,%0\n"
+		" addi     8,%1,%1\n"
+		" extru,<>  %0,3,4,%%r19\n"
+		" zdep,TR  %0,27,28,%0\n"
+		" addi     4,%1,%1\n"
+		" extru,<>  %0,1,2,%%r19\n"
+		" zdep,TR  %0,29,30,%0\n"
+		" addi     2,%1,%1\n"
+		" extru,=  %0,0,1,%%r19\n"
+		" addi     1,%1,%1\n"
+			: "+r" (x), "=r" (ret) );
+
+	return (int) ret;
+}
+
+static __inline__ int fls(int x)
+{
+	return x ? (__fls((unsigned long)x) + 1) : 0;
+}
 
 /*
  * hweightN: returns the hamming weight (i.e. the number