Messages in this thread | | | From | Gabriel Paubert <> | Date | Wed, 12 May 2004 23:11:24 +0200 | Subject | Re: [2.6.6-BK] x86_64 has buggy ffs() implementation |
| |
On Wed, May 12, 2004 at 08:31:56PM +0000, H. Peter Anvin wrote: > Followup to: <1084369416.16624.53.camel@imp.csi.cam.ac.uk> > By author: Anton Altaparmakov <aia21@cam.ac.uk> > In newsgroup: linux.dev.kernel > > > > Hi Andi, Andrew, Linus, > > > > x86_64 has incorrect include/asm-x86_64/bitops.h::ffs() implementation. > > It uses "g" instead of "rm" in the insline assembled bsfl instruction. > > (This was spotted by Yuri Per.) > > > > bsfl does not accept constant values but only memory ones. On i386 the > > correct "rm" is used. > > > > This causes NTFS build to fail as gcc optimizes a variable into a > > constant and ffs() then fails to assemble. > > > > Of course, this is a good reason to do a __builtin_constant_p() > wrapper that gcc can optimize: > > static __inline__ __attribute_const__ int ffs(int x) > { > if ( __builtin_constant_p(x) ) { > unsigned int y = (unsigned int)x; > if ( y >= 0x80000000 ) > return 32; > else if ( y >= 0x40000000 ) > return 31; > else if /* ... you get the idea ... */
Either I'm asleep or you are emulating bsrl, not bsfl. It should rather be:
if ( y & 0x00000001) return 1; if ( y & 0x00000002) return 2; if ( y & 0x00000004) return 3; ... if ( y & 0x80000000) return 32; return 0;
No need for the else clauses either because of the return. But maybe even __builtin_ffs(y) would work in this case.
Gabriel - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |