Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
6.5 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1995 - 1999
  3. Module Name:
  4. Align.h
  5. Abstract:
  6. Defines a macro for aligning an integer value or pointer
  7. to 0 mod 2^n for any n.
  8. Author:
  9. Mario Goertzel [MarioGo]
  10. Revision History:
  11. MarioGo 12-22-95 Bits 'n pieces
  12. MarioGo 02-19-96 Made type safe for C++.
  13. --*/
  14. #ifndef _ALIGN_H
  15. #define _ALIGN_H
  16. #ifdef __cplusplus
  17. //
  18. // The C++ interface looks like
  19. //
  20. // val = Align(val, 8) // returns val aligned to 0 mod 8
  21. // val = Align16(val); // returns val aligned to 0 mod 16
  22. //
  23. // Boths forms on the interface are equally efficient.
  24. //
  25. // Returns the argument aligned up to the nearest "0 mod factor" boundary. Has
  26. // no affect on values which are already aligned to 0 mod factor. The argument
  27. // maybe any integer or void pointer type.
  28. //
  29. //
  30. #define DECL_ALIGN_N(type) inline type Align( type value, int poft) \
  31. { \
  32. return (type)( ((unsigned long)(value) + ((poft)-1)) & ~(poft - 1) ); \
  33. }
  34. #define DECL_ALIGN(poft, type) inline type Align##poft ( type value ) \
  35. { \
  36. return Align(value, poft); \
  37. }
  38. #define DECL_PAD_N(type) inline unsigned int Pad( type value, int poft ) \
  39. { \
  40. return (-(long)value) & (poft - 1); \
  41. }
  42. #define DECL_PAD(poft, type) inline unsigned int Pad##poft (type value) \
  43. { \
  44. return Pad(value, poft); \
  45. }
  46. // same padding, but on pointer type size of argument
  47. #define DECL_ALIGN_PTR_N(type) inline type AlignPtr( type value, int poft) \
  48. { \
  49. return (type)( ((ULONG_PTR)(value) + ((poft)-1)) & ~(poft - 1) ); \
  50. }
  51. #define DECL_ALIGN_PTR(poft, type) inline type AlignPtr##poft ( type value ) \
  52. { \
  53. return AlignPtr(value, poft); \
  54. }
  55. #define DECL_PAD_PTR_N(type) inline unsigned int PadPtr( type value, int poft ) \
  56. { \
  57. return (unsigned int)((-(LONG_PTR)value) & (poft - 1)); \
  58. }
  59. #define DECL_PAD_PTR(poft, type) inline unsigned int PadPtr##poft (type value) \
  60. { \
  61. return PadPtr(value, poft); \
  62. }
  63. #define DECL_ALL_ALIGN(type) \
  64. DECL_ALIGN_N(type) \
  65. DECL_ALIGN(2, type) \
  66. DECL_ALIGN(4, type) \
  67. DECL_ALIGN(8, type) \
  68. DECL_ALIGN(16, type) \
  69. DECL_ALIGN(32, type)
  70. #define DECL_ALL_PAD(type) \
  71. DECL_PAD_N(type) \
  72. DECL_PAD(2, type) \
  73. DECL_PAD(4, type) \
  74. DECL_PAD(8, type) \
  75. DECL_PAD(16, type) \
  76. DECL_PAD(32, type)
  77. #define DECL_ALL_ALIGN_PTR(type) \
  78. DECL_ALIGN_PTR_N(type) \
  79. DECL_ALIGN_PTR(2, type) \
  80. DECL_ALIGN_PTR(4, type) \
  81. DECL_ALIGN_PTR(8, type) \
  82. DECL_ALIGN_PTR(16, type) \
  83. DECL_ALIGN_PTR(32, type)
  84. #define DECL_ALL_PAD_PTR(type) \
  85. DECL_PAD_PTR_N(type) \
  86. DECL_PAD_PTR(2, type) \
  87. DECL_PAD_PTR(4, type) \
  88. DECL_PAD_PTR(8, type) \
  89. DECL_PAD_PTR(16, type) \
  90. DECL_PAD_PTR(32, type)
  91. #define DECL_ALL_ALIGN_AND_PAD(type) \
  92. DECL_ALL_PAD(type) \
  93. DECL_ALL_ALIGN(type)
  94. #define DECL_ALL_ALIGN_AND_PAD_PTR(type) \
  95. DECL_ALL_PAD_PTR(type) \
  96. DECL_ALL_ALIGN_PTR(type)
  97. DECL_ALL_ALIGN_AND_PAD(short)
  98. DECL_ALL_ALIGN_AND_PAD(unsigned short)
  99. DECL_ALL_ALIGN_AND_PAD(long)
  100. DECL_ALL_ALIGN_AND_PAD(unsigned long)
  101. DECL_ALL_ALIGN_AND_PAD(int)
  102. DECL_ALL_ALIGN_AND_PAD(unsigned int)
  103. DECL_ALL_ALIGN_AND_PAD_PTR(void __RPC_FAR *)
  104. #ifdef _WIN64
  105. DECL_ALL_ALIGN_AND_PAD(unsigned __int64)
  106. #endif
  107. inline BOOL IsBufferAligned(PVOID p)
  108. {
  109. #if defined(_WIN64)
  110. return (((ULONG_PTR)p % 16) == 0);
  111. #else
  112. return (((ULONG_PTR)p % 8) == 0);
  113. #endif
  114. }
  115. inline BOOL IsBufferSizeAligned(size_t s)
  116. {
  117. #if defined(_WIN64)
  118. return ((s % 16) == 0);
  119. #else
  120. return ((s % 8) == 0);
  121. #endif
  122. }
  123. inline unsigned int PadToNaturalBoundary (unsigned int Value)
  124. {
  125. #if defined(_WIN64)
  126. return Pad16(Value);
  127. #else
  128. return Pad8(Value);
  129. #endif
  130. }
  131. inline PVOID AlignOnNaturalBoundary (PVOID Value)
  132. {
  133. #if defined(_WIN64)
  134. return AlignPtr16(Value);
  135. #else
  136. return AlignPtr8(Value);
  137. #endif
  138. }
  139. // required for global constant expressions
  140. #define ConstPadN(p, poft) ( (-(long)p) & (poft - 1) )
  141. #if defined(_WIN64)
  142. #define RPCRT_DEFAULT_STRUCT_ALIGNMENT 8
  143. #else
  144. #define RPCRT_DEFAULT_STRUCT_ALIGNMENT 4
  145. #endif
  146. #define SIZE_OF_OBJECT_AND_PADDING(ObjectType) \
  147. (sizeof(ObjectType) + ConstPadN(sizeof(ObjectType), RPCRT_DEFAULT_STRUCT_ALIGNMENT))
  148. #else
  149. // C interface.
  150. #define AlignN(p, poft) ( ((unsigned long)(p) + ((poft)-1)) & ~(poft - 1) )
  151. #define PadN(p, poft) ( (-(long)p) & (poft - 1) )
  152. #ifdef DOS
  153. #define AlignPtrN(value, poft) (void __far *)AlignN(value, poft)
  154. #define AlignNearPtrN(value, poft) (void __near *)AlignN(value, poft)
  155. #else
  156. #define AlignPtrN(value, poft) (void *)AlignN(value, poft)
  157. #define AlignNearPtrN(value, poft) (void *)AlignN(value, poft)
  158. #endif
  159. // For aligning integer values
  160. #define Align2(p) AlignN((p), 2)
  161. #define Align4(p) AlignN((p), 4)
  162. #define Align8(p) AlignN((p), 8)
  163. #define Align16(p) AlignN((p), 16)
  164. #define Align32(p) AlignN((p), 32)
  165. // For aligning pointers
  166. #define AlignPtr2(p) AlignPtrN((p), 2)
  167. #define AlignPtr4(p) AlignPtrN((p), 4)
  168. #define AlignPtr8(p) AlignPtrN((p), 8)
  169. #define AlignPtr16(p) AlignPtrN((p), 16)
  170. #define AlignPtr32(p) AlignPtrN((p), 32)
  171. // For near pointers
  172. #define AlignNearPtr2(p) AlignNearPtrN((p), 2)
  173. #define AlignNearPtr4(p) AlignNearPtrN((p), 4)
  174. #define AlignNearPtr8(p) AlignNearPtrN((p), 8)
  175. #define AlignNearPtr16(p) AlignNearPtrN((p), 16)
  176. #define AlignNearPtr32(p) AlignNearPtrN((p), 32)
  177. // For everything
  178. #define Pad2(p) PadN((p), 2)
  179. #define Pad4(p) PadN((p), 4)
  180. #define Pad8(p) PadN((p), 8)
  181. #define Pad16(p) PadN((p), 16)
  182. #define Pad32(p) PadN((p), 32)
  183. #endif // __cplusplus
  184. #endif // _ALIGN_H