mem.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
  2. /*
  3. * Copyright (c) Yann Collet, Facebook, Inc.
  4. * All rights reserved.
  5. *
  6. * This source code is licensed under both the BSD-style license (found in the
  7. * LICENSE file in the root directory of this source tree) and the GPLv2 (found
  8. * in the COPYING file in the root directory of this source tree).
  9. * You may select, at your option, one of the above-listed licenses.
  10. */
  11. #ifndef MEM_H_MODULE
  12. #define MEM_H_MODULE
  13. /*-****************************************
  14. * Dependencies
  15. ******************************************/
  16. #include <asm/unaligned.h> /* get_unaligned, put_unaligned* */
  17. #include <linux/compiler.h> /* inline */
  18. #include <linux/swab.h> /* swab32, swab64 */
  19. #include <linux/types.h> /* size_t, ptrdiff_t */
  20. #include "debug.h" /* DEBUG_STATIC_ASSERT */
  21. /*-****************************************
  22. * Compiler specifics
  23. ******************************************/
  24. #define MEM_STATIC static inline
  25. /*-**************************************************************
  26. * Basic Types
  27. *****************************************************************/
  28. typedef uint8_t BYTE;
  29. typedef uint8_t U8;
  30. typedef int8_t S8;
  31. typedef uint16_t U16;
  32. typedef int16_t S16;
  33. typedef uint32_t U32;
  34. typedef int32_t S32;
  35. typedef uint64_t U64;
  36. typedef int64_t S64;
  37. /*-**************************************************************
  38. * Memory I/O API
  39. *****************************************************************/
  40. /*=== Static platform detection ===*/
  41. MEM_STATIC unsigned MEM_32bits(void);
  42. MEM_STATIC unsigned MEM_64bits(void);
  43. MEM_STATIC unsigned MEM_isLittleEndian(void);
  44. /*=== Native unaligned read/write ===*/
  45. MEM_STATIC U16 MEM_read16(const void* memPtr);
  46. MEM_STATIC U32 MEM_read32(const void* memPtr);
  47. MEM_STATIC U64 MEM_read64(const void* memPtr);
  48. MEM_STATIC size_t MEM_readST(const void* memPtr);
  49. MEM_STATIC void MEM_write16(void* memPtr, U16 value);
  50. MEM_STATIC void MEM_write32(void* memPtr, U32 value);
  51. MEM_STATIC void MEM_write64(void* memPtr, U64 value);
  52. /*=== Little endian unaligned read/write ===*/
  53. MEM_STATIC U16 MEM_readLE16(const void* memPtr);
  54. MEM_STATIC U32 MEM_readLE24(const void* memPtr);
  55. MEM_STATIC U32 MEM_readLE32(const void* memPtr);
  56. MEM_STATIC U64 MEM_readLE64(const void* memPtr);
  57. MEM_STATIC size_t MEM_readLEST(const void* memPtr);
  58. MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val);
  59. MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val);
  60. MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32);
  61. MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64);
  62. MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val);
  63. /*=== Big endian unaligned read/write ===*/
  64. MEM_STATIC U32 MEM_readBE32(const void* memPtr);
  65. MEM_STATIC U64 MEM_readBE64(const void* memPtr);
  66. MEM_STATIC size_t MEM_readBEST(const void* memPtr);
  67. MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32);
  68. MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64);
  69. MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val);
  70. /*=== Byteswap ===*/
  71. MEM_STATIC U32 MEM_swap32(U32 in);
  72. MEM_STATIC U64 MEM_swap64(U64 in);
  73. MEM_STATIC size_t MEM_swapST(size_t in);
  74. /*-**************************************************************
  75. * Memory I/O Implementation
  76. *****************************************************************/
  77. MEM_STATIC unsigned MEM_32bits(void)
  78. {
  79. return sizeof(size_t) == 4;
  80. }
  81. MEM_STATIC unsigned MEM_64bits(void)
  82. {
  83. return sizeof(size_t) == 8;
  84. }
  85. #if defined(__LITTLE_ENDIAN)
  86. #define MEM_LITTLE_ENDIAN 1
  87. #else
  88. #define MEM_LITTLE_ENDIAN 0
  89. #endif
  90. MEM_STATIC unsigned MEM_isLittleEndian(void)
  91. {
  92. return MEM_LITTLE_ENDIAN;
  93. }
  94. MEM_STATIC U16 MEM_read16(const void *memPtr)
  95. {
  96. return get_unaligned((const U16 *)memPtr);
  97. }
  98. MEM_STATIC U32 MEM_read32(const void *memPtr)
  99. {
  100. return get_unaligned((const U32 *)memPtr);
  101. }
  102. MEM_STATIC U64 MEM_read64(const void *memPtr)
  103. {
  104. return get_unaligned((const U64 *)memPtr);
  105. }
  106. MEM_STATIC size_t MEM_readST(const void *memPtr)
  107. {
  108. return get_unaligned((const size_t *)memPtr);
  109. }
  110. MEM_STATIC void MEM_write16(void *memPtr, U16 value)
  111. {
  112. put_unaligned(value, (U16 *)memPtr);
  113. }
  114. MEM_STATIC void MEM_write32(void *memPtr, U32 value)
  115. {
  116. put_unaligned(value, (U32 *)memPtr);
  117. }
  118. MEM_STATIC void MEM_write64(void *memPtr, U64 value)
  119. {
  120. put_unaligned(value, (U64 *)memPtr);
  121. }
  122. /*=== Little endian r/w ===*/
  123. MEM_STATIC U16 MEM_readLE16(const void *memPtr)
  124. {
  125. return get_unaligned_le16(memPtr);
  126. }
  127. MEM_STATIC void MEM_writeLE16(void *memPtr, U16 val)
  128. {
  129. put_unaligned_le16(val, memPtr);
  130. }
  131. MEM_STATIC U32 MEM_readLE24(const void *memPtr)
  132. {
  133. return MEM_readLE16(memPtr) + (((const BYTE *)memPtr)[2] << 16);
  134. }
  135. MEM_STATIC void MEM_writeLE24(void *memPtr, U32 val)
  136. {
  137. MEM_writeLE16(memPtr, (U16)val);
  138. ((BYTE *)memPtr)[2] = (BYTE)(val >> 16);
  139. }
  140. MEM_STATIC U32 MEM_readLE32(const void *memPtr)
  141. {
  142. return get_unaligned_le32(memPtr);
  143. }
  144. MEM_STATIC void MEM_writeLE32(void *memPtr, U32 val32)
  145. {
  146. put_unaligned_le32(val32, memPtr);
  147. }
  148. MEM_STATIC U64 MEM_readLE64(const void *memPtr)
  149. {
  150. return get_unaligned_le64(memPtr);
  151. }
  152. MEM_STATIC void MEM_writeLE64(void *memPtr, U64 val64)
  153. {
  154. put_unaligned_le64(val64, memPtr);
  155. }
  156. MEM_STATIC size_t MEM_readLEST(const void *memPtr)
  157. {
  158. if (MEM_32bits())
  159. return (size_t)MEM_readLE32(memPtr);
  160. else
  161. return (size_t)MEM_readLE64(memPtr);
  162. }
  163. MEM_STATIC void MEM_writeLEST(void *memPtr, size_t val)
  164. {
  165. if (MEM_32bits())
  166. MEM_writeLE32(memPtr, (U32)val);
  167. else
  168. MEM_writeLE64(memPtr, (U64)val);
  169. }
  170. /*=== Big endian r/w ===*/
  171. MEM_STATIC U32 MEM_readBE32(const void *memPtr)
  172. {
  173. return get_unaligned_be32(memPtr);
  174. }
  175. MEM_STATIC void MEM_writeBE32(void *memPtr, U32 val32)
  176. {
  177. put_unaligned_be32(val32, memPtr);
  178. }
  179. MEM_STATIC U64 MEM_readBE64(const void *memPtr)
  180. {
  181. return get_unaligned_be64(memPtr);
  182. }
  183. MEM_STATIC void MEM_writeBE64(void *memPtr, U64 val64)
  184. {
  185. put_unaligned_be64(val64, memPtr);
  186. }
  187. MEM_STATIC size_t MEM_readBEST(const void *memPtr)
  188. {
  189. if (MEM_32bits())
  190. return (size_t)MEM_readBE32(memPtr);
  191. else
  192. return (size_t)MEM_readBE64(memPtr);
  193. }
  194. MEM_STATIC void MEM_writeBEST(void *memPtr, size_t val)
  195. {
  196. if (MEM_32bits())
  197. MEM_writeBE32(memPtr, (U32)val);
  198. else
  199. MEM_writeBE64(memPtr, (U64)val);
  200. }
  201. MEM_STATIC U32 MEM_swap32(U32 in)
  202. {
  203. return swab32(in);
  204. }
  205. MEM_STATIC U64 MEM_swap64(U64 in)
  206. {
  207. return swab64(in);
  208. }
  209. MEM_STATIC size_t MEM_swapST(size_t in)
  210. {
  211. if (MEM_32bits())
  212. return (size_t)MEM_swap32((U32)in);
  213. else
  214. return (size_t)MEM_swap64((U64)in);
  215. }
  216. #endif /* MEM_H_MODULE */