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