uboot/arch/powerpc/include/asm/byteorder.h
<<
>>
Prefs
   1#ifndef _PPC_BYTEORDER_H
   2#define _PPC_BYTEORDER_H
   3
   4#include <asm/types.h>
   5
   6#ifdef __GNUC__
   7
   8static __inline__ unsigned ld_le16(const volatile unsigned short *addr)
   9{
  10        unsigned val;
  11
  12        __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
  13        return val;
  14}
  15
  16static __inline__ void st_le16(volatile unsigned short *addr, const unsigned val)
  17{
  18        __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
  19}
  20
  21static __inline__ unsigned ld_le32(const volatile unsigned *addr)
  22{
  23        unsigned val;
  24
  25        __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
  26        return val;
  27}
  28
  29static __inline__ void st_le32(volatile unsigned *addr, const unsigned val)
  30{
  31        __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
  32}
  33
  34/* alas, egcs sounds like it has a bug in this code that doesn't use the
  35   inline asm correctly, and can cause file corruption. Until I hear that
  36   it's fixed, I can live without the extra speed. I hope. */
  37#if !(__GNUC__ >= 2 && __GNUC_MINOR__ >= 90)
  38#if 0
  39#  define __arch_swab16(x) ld_le16(&x)
  40#  define __arch_swab32(x) ld_le32(&x)
  41#else
  42static __inline__ __attribute__((const)) __u16 ___arch__swab16(__u16 value)
  43{
  44        __u16 result;
  45
  46        __asm__("rlwimi %0,%1,8,16,23"
  47            : "=r" (result)
  48            : "r" (value), "0" (value >> 8));
  49        return result;
  50}
  51
  52static __inline__ __attribute__((const)) __u32 ___arch__swab32(__u32 value)
  53{
  54        __u32 result;
  55
  56        __asm__("rlwimi %0,%1,24,16,23\n\t"
  57            "rlwimi %0,%1,8,8,15\n\t"
  58            "rlwimi %0,%1,24,0,7"
  59            : "=r" (result)
  60            : "r" (value), "0" (value >> 24));
  61        return result;
  62}
  63#define __arch__swab32(x) ___arch__swab32(x)
  64#define __arch__swab16(x) ___arch__swab16(x)
  65#endif /* 0 */
  66
  67#endif
  68
  69/* The same, but returns converted value from the location pointer by addr. */
  70#define __arch__swab16p(addr) ld_le16(addr)
  71#define __arch__swab32p(addr) ld_le32(addr)
  72
  73/* The same, but do the conversion in situ, ie. put the value back to addr. */
  74#define __arch__swab16s(addr) st_le16(addr,*addr)
  75#define __arch__swab32s(addr) st_le32(addr,*addr)
  76
  77#endif /* __GNUC__ */
  78
  79#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
  80#define __BYTEORDER_HAS_U64__
  81#endif
  82#include <linux/byteorder/big_endian.h>
  83
  84#endif /* _PPC_BYTEORDER_H */
  85