in_be64() assembly
Linas Vepstas
linas at austin.ibm.com
Wed Jan 5 11:10:16 EST 2005
On Tue, Jan 04, 2005 at 04:13:54PM -0600, Jake Moilanen was heard to remark:
>
> diff -puN include/asm-ppc64/io.h~in_be64-fix include/asm-ppc64/io.h
> --- linux-2.6-bk/include/asm-ppc64/io.h~in_be64-fix Tue Jan 4 15:33:22 2005
> +++ linux-2.6-bk-moilanen/include/asm-ppc64/io.h Tue Jan 4 15:59:50 2005
> @@ -372,7 +372,7 @@ static inline unsigned long in_be64(cons
> unsigned long ret;
>
> __asm__ __volatile__("ld %0,0(%1); twi 0,%0,0; isync"
> - : "=r" (ret) : "m" (*addr));
> + : "=r" (ret) : "b" (*addr));
> return ret;
> }
Very weird. Why anyone thought that doing a load with a zero offset
is somehow 'correct' seems strange to me. The compiler is quite
capable of computing offsets, and I don't see any aliasing issues.
Certainly the 8, 16 and 32-bit versions doen't do this kind of
funny business.
Does the following work?
static inline unsigned long in_be64(const whatever ...)
{
unsigned long ret;
__asm__ __volatile__("ld %0,%1; twi 0,%0,0; isync"
: "=r" (ret) : "m" (*addr));
return ret;
}
I suspect in_le64 is also borken, it should be
"ld %1,%2\n"
...with
: "=r" (ret) , "=r" (tmp) : "m" (*addr) ,
instead of the b.
out_le64 looks broken in the same way.
--linas
More information about the Linuxppc64-dev
mailing list