aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-xtensa
diff options
context:
space:
mode:
authorChris Zankel <chris@zankel.net>2007-05-31 20:41:14 -0400
committerChris Zankel <chris@zankel.net>2007-05-31 20:41:14 -0400
commitef6051a90e2ad1af636e99d1d4603fdcf2adfcbe (patch)
treeac64477663d0163161f3646cda4e5dd0c1e21893 /include/asm-xtensa
parent3f0a6766e0cc5a577805732e5adb50a585c58175 (diff)
[XTENSA] fix bit operations in bitops.h
A macro used internally in the bitops.h file to identify the number of leading zeros (__cntlz) was implemented incorrectly for Xtensa processors that don't provide the 'nsa/nsau' instructions. As a result, the dependent functions and macros (ffs, ffz, fls) were broken. Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'include/asm-xtensa')
-rw-r--r--include/asm-xtensa/bitops.h60
1 files changed, 26 insertions, 34 deletions
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h
index d815649617aa..96303dff3ee4 100644
--- a/include/asm-xtensa/bitops.h
+++ b/include/asm-xtensa/bitops.h
@@ -7,7 +7,7 @@
7 * License. See the file "COPYING" in the main directory of this archive 7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details. 8 * for more details.
9 * 9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc. 10 * Copyright (C) 2001 - 2007 Tensilica Inc.
11 */ 11 */
12 12
13#ifndef _XTENSA_BITOPS_H 13#ifndef _XTENSA_BITOPS_H
@@ -31,64 +31,44 @@
31 31
32#if XCHAL_HAVE_NSA 32#if XCHAL_HAVE_NSA
33 33
34static __inline__ int __cntlz (unsigned long x) 34static inline unsigned long __cntlz (unsigned long x)
35{ 35{
36 int lz; 36 int lz;
37 asm ("nsau %0, %1" : "=r" (lz) : "r" (x)); 37 asm ("nsau %0, %1" : "=r" (lz) : "r" (x));
38 return 31 - lz; 38 return lz;
39} 39}
40 40
41#else
42
43static __inline__ int __cntlz (unsigned long x)
44{
45 unsigned long sum, x1, x2, x4, x8, x16;
46 x1 = x & 0xAAAAAAAA;
47 x2 = x & 0xCCCCCCCC;
48 x4 = x & 0xF0F0F0F0;
49 x8 = x & 0xFF00FF00;
50 x16 = x & 0xFFFF0000;
51 sum = x2 ? 2 : 0;
52 sum += (x16 != 0) * 16;
53 sum += (x8 != 0) * 8;
54 sum += (x4 != 0) * 4;
55 sum += (x1 != 0);
56
57 return sum;
58}
59
60#endif
61
62/* 41/*
63 * ffz: Find first zero in word. Undefined if no zero exists. 42 * ffz: Find first zero in word. Undefined if no zero exists.
64 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). 43 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
65 */ 44 */
66 45
67static __inline__ int ffz(unsigned long x) 46static inline int ffz(unsigned long x)
68{ 47{
69 if ((x = ~x) == 0) 48 return 31 - __cntlz(~x & -~x);
70 return 32;
71 return __cntlz(x & -x);
72} 49}
73 50
74/* 51/*
75 * __ffs: Find first bit set in word. Return 0 for bit 0 52 * __ffs: Find first bit set in word. Return 0 for bit 0
76 */ 53 */
77 54
78static __inline__ int __ffs(unsigned long x) 55static inline int __ffs(unsigned long x)
79{ 56{
80 return __cntlz(x & -x); 57 return 31 - __cntlz(x & -x);
81} 58}
82 59
60
61#ifdef __KERNEL__
62
83/* 63/*
84 * ffs: Find first bit set in word. This is defined the same way as 64 * ffs: Find first bit set in word. This is defined the same way as
85 * the libc and compiler builtin ffs routines, therefore 65 * the libc and compiler builtin ffs routines, therefore
86 * differs in spirit from the above ffz (man ffs). 66 * differs in spirit from the above ffz (man ffs).
87 */ 67 */
88 68
89static __inline__ int ffs(unsigned long x) 69static inline int ffs(unsigned long x)
90{ 70{
91 return __cntlz(x & -x) + 1; 71 return 32 - __cntlz(x & -x);
92} 72}
93 73
94/* 74/*
@@ -96,10 +76,22 @@ static __inline__ int ffs(unsigned long x)
96 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. 76 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
97 */ 77 */
98 78
99static __inline__ int fls (unsigned int x) 79static inline int fls (unsigned int x)
100{ 80{
101 return __cntlz(x); 81 return 32 - __cntlz(x);
102} 82}
83
84#else
85
86/* Use the generic implementation if we don't have the nsa/nsau instructions. */
87
88# include <asm-generic/bitops/ffs.h>
89# include <asm-generic/bitops/__ffs.h>
90# include <asm-generic/bitops/ffz.h>
91# include <asm-generic/bitops/fls.h>
92
93#endif
94
103#include <asm-generic/bitops/fls64.h> 95#include <asm-generic/bitops/fls64.h>
104#include <asm-generic/bitops/find.h> 96#include <asm-generic/bitops/find.h>
105#include <asm-generic/bitops/ext2-non-atomic.h> 97#include <asm-generic/bitops/ext2-non-atomic.h>