unaligned.h
上传用户:szlgq88
上传日期:2009-04-28
资源大小:48287k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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