home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-generic / unaligned.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  2.7 KB  |  123 lines

  1. #ifndef _ASM_GENERIC_UNALIGNED_H_
  2. #define _ASM_GENERIC_UNALIGNED_H_
  3.  
  4. /*
  5.  * For the benefit of those who are trying to port Linux to another
  6.  * architecture, here are some C-language equivalents. 
  7.  *
  8.  * This is based almost entirely upon Richard Henderson's
  9.  * asm-alpha/unaligned.h implementation.  Some comments were
  10.  * taken from David Mosberger's asm-ia64/unaligned.h header.
  11.  */
  12.  
  13. #include <linux/types.h>
  14.  
  15. /* 
  16.  * The main single-value unaligned transfer routines.
  17.  */
  18. #define get_unaligned(ptr) \
  19.     __get_unaligned((ptr), sizeof(*(ptr)))
  20. #define put_unaligned(x,ptr) \
  21.     __put_unaligned((__u64)(x), (ptr), sizeof(*(ptr)))
  22.  
  23. /*
  24.  * This function doesn't actually exist.  The idea is that when
  25.  * someone uses the macros below with an unsupported size (datatype),
  26.  * the linker will alert us to the problem via an unresolved reference
  27.  * error.
  28.  */
  29. extern void bad_unaligned_access_length(void) __attribute__((noreturn));
  30.  
  31. struct __una_u64 { __u64 x __attribute__((packed)); };
  32. struct __una_u32 { __u32 x __attribute__((packed)); };
  33. struct __una_u16 { __u16 x __attribute__((packed)); };
  34.  
  35. /*
  36.  * Elemental unaligned loads 
  37.  */
  38.  
  39. static inline __u64 __uldq(const __u64 *addr)
  40. {
  41.     const struct __una_u64 *ptr = (const struct __una_u64 *) addr;
  42.     return ptr->x;
  43. }
  44.  
  45. static inline __u32 __uldl(const __u32 *addr)
  46. {
  47.     const struct __una_u32 *ptr = (const struct __una_u32 *) addr;
  48.     return ptr->x;
  49. }
  50.  
  51. static inline __u16 __uldw(const __u16 *addr)
  52. {
  53.     const struct __una_u16 *ptr = (const struct __una_u16 *) addr;
  54.     return ptr->x;
  55. }
  56.  
  57. /*
  58.  * Elemental unaligned stores 
  59.  */
  60.  
  61. static inline void __ustq(__u64 val, __u64 *addr)
  62. {
  63.     struct __una_u64 *ptr = (struct __una_u64 *) addr;
  64.     ptr->x = val;
  65. }
  66.  
  67. static inline void __ustl(__u32 val, __u32 *addr)
  68. {
  69.     struct __una_u32 *ptr = (struct __una_u32 *) addr;
  70.     ptr->x = val;
  71. }
  72.  
  73. static inline void __ustw(__u16 val, __u16 *addr)
  74. {
  75.     struct __una_u16 *ptr = (struct __una_u16 *) addr;
  76.     ptr->x = val;
  77. }
  78.  
  79. #define __get_unaligned(ptr, size) ({        \
  80.     const void *__gu_p = ptr;        \
  81.     __u64 val;                \
  82.     switch (size) {                \
  83.     case 1:                    \
  84.         val = *(const __u8 *)__gu_p;    \
  85.         break;                \
  86.     case 2:                    \
  87.         val = __uldw(__gu_p);        \
  88.         break;                \
  89.     case 4:                    \
  90.         val = __uldl(__gu_p);        \
  91.         break;                \
  92.     case 8:                    \
  93.         val = __uldq(__gu_p);        \
  94.         break;                \
  95.     default:                \
  96.         bad_unaligned_access_length();    \
  97.     };                    \
  98.     (__typeof__(*(ptr)))val;        \
  99. })
  100.  
  101. #define __put_unaligned(val, ptr, size)        \
  102. do {                        \
  103.     void *__gu_p = ptr;            \
  104.     switch (size) {                \
  105.     case 1:                    \
  106.         *(__u8 *)__gu_p = val;        \
  107.             break;                \
  108.     case 2:                    \
  109.         __ustw(val, __gu_p);        \
  110.         break;                \
  111.     case 4:                    \
  112.         __ustl(val, __gu_p);        \
  113.         break;                \
  114.     case 8:                    \
  115.         __ustq(val, __gu_p);        \
  116.         break;                \
  117.     default:                \
  118.             bad_unaligned_access_length();    \
  119.     };                    \
  120. } while(0)
  121.  
  122. #endif /* _ASM_GENERIC_UNALIGNED_H */
  123.