cpu_endian.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /**
  2. * @file cpu_endian.h
  3. * @brief Byte order conversion
  4. *
  5. * @section License
  6. *
  7. * SPDX-License-Identifier: GPL-2.0-or-later
  8. *
  9. * Copyright (C) 2010-2023 Oryx Embedded SARL. All rights reserved.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License
  13. * as published by the Free Software Foundation; either version 2
  14. * of the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software Foundation,
  23. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  24. *
  25. * @author Oryx Embedded SARL (www.oryx-embedded.com)
  26. * @version 2.2.4
  27. **/
  28. #ifndef _CPU_ENDIAN_H
  29. #define _CPU_ENDIAN_H
  30. //Dependencies
  31. #include "os_port.h"
  32. //Undefine conflicting definitions
  33. #ifdef HTONS
  34. #undef HTONS
  35. #endif
  36. #ifdef HTONL
  37. #undef HTONL
  38. #endif
  39. #ifdef HTONLL
  40. #undef HTONLL
  41. #endif
  42. #ifdef htons
  43. #undef htons
  44. #endif
  45. #ifdef htonl
  46. #undef htonl
  47. #endif
  48. #ifdef htonll
  49. #undef htonll
  50. #endif
  51. #ifdef NTOHS
  52. #undef NTOHS
  53. #endif
  54. #ifdef NTOHL
  55. #undef NTOHL
  56. #endif
  57. #ifdef NTOHLL
  58. #undef NTOHLL
  59. #endif
  60. #ifdef ntohs
  61. #undef ntohs
  62. #endif
  63. #ifdef ntohl
  64. #undef ntohl
  65. #endif
  66. #ifdef ntohll
  67. #undef ntohll
  68. #endif
  69. #ifdef HTOLE16
  70. #undef HTOLE16
  71. #endif
  72. #ifdef HTOLE32
  73. #undef HTOLE32
  74. #endif
  75. #ifdef HTOLE64
  76. #undef HTOLE64
  77. #endif
  78. #ifdef htole16
  79. #undef htole16
  80. #endif
  81. #ifdef htole32
  82. #undef htole32
  83. #endif
  84. #ifdef htole64
  85. #undef htole64
  86. #endif
  87. #ifdef LETOH16
  88. #undef LETOH16
  89. #endif
  90. #ifdef LETOH32
  91. #undef LETOH32
  92. #endif
  93. #ifdef LETOH64
  94. #undef LETOH64
  95. #endif
  96. #ifdef letoh16
  97. #undef letoh16
  98. #endif
  99. #ifdef letoh32
  100. #undef letoh32
  101. #endif
  102. #ifdef letoh64
  103. #undef letoh64
  104. #endif
  105. #ifdef HTOBE16
  106. #undef HTOBE16
  107. #endif
  108. #ifdef HTOBE32
  109. #undef HTOBE32
  110. #endif
  111. #ifdef HTOBE64
  112. #undef HTOBE64
  113. #endif
  114. #ifdef htobe16
  115. #undef htobe16
  116. #endif
  117. #ifdef htobe32
  118. #undef htobe32
  119. #endif
  120. #ifdef htobe64
  121. #undef htobe64
  122. #endif
  123. #ifdef BETOH16
  124. #undef BETOH16
  125. #endif
  126. #ifdef BETOH32
  127. #undef BETOH32
  128. #endif
  129. #ifdef BETOH64
  130. #undef BETOH64
  131. #endif
  132. #ifdef betoh16
  133. #undef betoh16
  134. #endif
  135. #ifdef betoh32
  136. #undef betoh32
  137. #endif
  138. #ifdef betoh64
  139. #undef betoh64
  140. #endif
  141. //Load unaligned 16-bit integer (little-endian encoding)
  142. #define LOAD16LE(p) ( \
  143. ((uint16_t)(((uint8_t *)(p))[0]) << 0) | \
  144. ((uint16_t)(((uint8_t *)(p))[1]) << 8))
  145. //Load unaligned 16-bit integer (big-endian encoding)
  146. #define LOAD16BE(p) ( \
  147. ((uint16_t)(((uint8_t *)(p))[0]) << 8) | \
  148. ((uint16_t)(((uint8_t *)(p))[1]) << 0))
  149. //Load unaligned 24-bit integer (little-endian encoding)
  150. #define LOAD24LE(p) ( \
  151. ((uint32_t)(((uint8_t *)(p))[0]) << 0)| \
  152. ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
  153. ((uint32_t)(((uint8_t *)(p))[2]) << 16))
  154. //Load unaligned 24-bit integer (big-endian encoding)
  155. #define LOAD24BE(p) ( \
  156. ((uint32_t)(((uint8_t *)(p))[0]) << 16) | \
  157. ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
  158. ((uint32_t)(((uint8_t *)(p))[2]) << 0))
  159. //Load unaligned 32-bit integer (little-endian encoding)
  160. #define LOAD32LE(p) ( \
  161. ((uint32_t)(((uint8_t *)(p))[0]) << 0) | \
  162. ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \
  163. ((uint32_t)(((uint8_t *)(p))[2]) << 16) | \
  164. ((uint32_t)(((uint8_t *)(p))[3]) << 24))
  165. //Load unaligned 32-bit integer (big-endian encoding)
  166. #define LOAD32BE(p) ( \
  167. ((uint32_t)(((uint8_t *)(p))[0]) << 24) | \
  168. ((uint32_t)(((uint8_t *)(p))[1]) << 16) | \
  169. ((uint32_t)(((uint8_t *)(p))[2]) << 8) | \
  170. ((uint32_t)(((uint8_t *)(p))[3]) << 0))
  171. //Load unaligned 48-bit integer (little-endian encoding)
  172. #define LOAD48LE(p) ( \
  173. ((uint64_t)(((uint8_t *)(p))[0]) << 0) | \
  174. ((uint64_t)(((uint8_t *)(p))[1]) << 8) | \
  175. ((uint64_t)(((uint8_t *)(p))[2]) << 16) | \
  176. ((uint64_t)(((uint8_t *)(p))[3]) << 24) | \
  177. ((uint64_t)(((uint8_t *)(p))[4]) << 32) | \
  178. ((uint64_t)(((uint8_t *)(p))[5]) << 40)
  179. //Load unaligned 48-bit integer (big-endian encoding)
  180. #define LOAD48BE(p) ( \
  181. ((uint64_t)(((uint8_t *)(p))[0]) << 40) | \
  182. ((uint64_t)(((uint8_t *)(p))[1]) << 32) | \
  183. ((uint64_t)(((uint8_t *)(p))[2]) << 24) | \
  184. ((uint64_t)(((uint8_t *)(p))[3]) << 16) | \
  185. ((uint64_t)(((uint8_t *)(p))[4]) << 8) | \
  186. ((uint64_t)(((uint8_t *)(p))[5]) << 0))
  187. //Load unaligned 64-bit integer (little-endian encoding)
  188. #define LOAD64LE(p) ( \
  189. ((uint64_t)(((uint8_t *)(p))[0]) << 0) | \
  190. ((uint64_t)(((uint8_t *)(p))[1]) << 8) | \
  191. ((uint64_t)(((uint8_t *)(p))[2]) << 16) | \
  192. ((uint64_t)(((uint8_t *)(p))[3]) << 24) | \
  193. ((uint64_t)(((uint8_t *)(p))[4]) << 32) | \
  194. ((uint64_t)(((uint8_t *)(p))[5]) << 40) | \
  195. ((uint64_t)(((uint8_t *)(p))[6]) << 48) | \
  196. ((uint64_t)(((uint8_t *)(p))[7]) << 56))
  197. //Load unaligned 64-bit integer (big-endian encoding)
  198. #define LOAD64BE(p) ( \
  199. ((uint64_t)(((uint8_t *)(p))[0]) << 56) | \
  200. ((uint64_t)(((uint8_t *)(p))[1]) << 48) | \
  201. ((uint64_t)(((uint8_t *)(p))[2]) << 40) | \
  202. ((uint64_t)(((uint8_t *)(p))[3]) << 32) | \
  203. ((uint64_t)(((uint8_t *)(p))[4]) << 24) | \
  204. ((uint64_t)(((uint8_t *)(p))[5]) << 16) | \
  205. ((uint64_t)(((uint8_t *)(p))[6]) << 8) | \
  206. ((uint64_t)(((uint8_t *)(p))[7]) << 0))
  207. //Store unaligned 16-bit integer (little-endian encoding)
  208. #define STORE16LE(a, p) \
  209. ((uint8_t *)(p))[0] = ((uint16_t)(a) >> 0) & 0xFFU, \
  210. ((uint8_t *)(p))[1] = ((uint16_t)(a) >> 8) & 0xFFU
  211. //Store unaligned 16-bit integer (big-endian encoding)
  212. #define STORE16BE(a, p) \
  213. ((uint8_t *)(p))[0] = ((uint16_t)(a) >> 8) & 0xFFU, \
  214. ((uint8_t *)(p))[1] = ((uint16_t)(a) >> 0) & 0xFFU
  215. //Store unaligned 24-bit integer (little-endian encoding)
  216. #define STORE24LE(a, p) \
  217. ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 0) & 0xFFU, \
  218. ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
  219. ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 16) & 0xFFU
  220. //Store unaligned 24-bit integer (big-endian encoding)
  221. #define STORE24BE(a, p) \
  222. ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 16) & 0xFFU, \
  223. ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
  224. ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 0) & 0xFFU
  225. //Store unaligned 32-bit integer (little-endian encoding)
  226. #define STORE32LE(a, p) \
  227. ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 0) & 0xFFU, \
  228. ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \
  229. ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 16) & 0xFFU, \
  230. ((uint8_t *)(p))[3] = ((uint32_t)(a) >> 24) & 0xFFU
  231. //Store unaligned 32-bit integer (big-endian encoding)
  232. #define STORE32BE(a, p) \
  233. ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 24) & 0xFFU, \
  234. ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 16) & 0xFFU, \
  235. ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 8) & 0xFFU, \
  236. ((uint8_t *)(p))[3] = ((uint32_t)(a) >> 0) & 0xFFU
  237. //Store unaligned 48-bit integer (little-endian encoding)
  238. #define STORE48LE(a, p) \
  239. ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 0) & 0xFFU, \
  240. ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 8) & 0xFFU, \
  241. ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 16) & 0xFFU, \
  242. ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 24) & 0xFFU, \
  243. ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 32) & 0xFFU, \
  244. ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 40) & 0xFFU,
  245. //Store unaligned 48-bit integer (big-endian encoding)
  246. #define STORE48BE(a, p) \
  247. ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 40) & 0xFFU, \
  248. ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 32) & 0xFFU, \
  249. ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 24) & 0xFFU, \
  250. ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 16) & 0xFFU, \
  251. ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 8) & 0xFFU, \
  252. ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 0) & 0xFFU
  253. //Store unaligned 64-bit integer (little-endian encoding)
  254. #define STORE64LE(a, p) \
  255. ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 0) & 0xFFU, \
  256. ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 8) & 0xFFU, \
  257. ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 16) & 0xFFU, \
  258. ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 24) & 0xFFU, \
  259. ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 32) & 0xFFU, \
  260. ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 40) & 0xFFU, \
  261. ((uint8_t *)(p))[6] = ((uint64_t)(a) >> 48) & 0xFFU, \
  262. ((uint8_t *)(p))[7] = ((uint64_t)(a) >> 56) & 0xFFU
  263. //Store unaligned 64-bit integer (big-endian encoding)
  264. #define STORE64BE(a, p) \
  265. ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 56) & 0xFFU, \
  266. ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 48) & 0xFFU, \
  267. ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 40) & 0xFFU, \
  268. ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 32) & 0xFFU, \
  269. ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 24) & 0xFFU, \
  270. ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 16) & 0xFFU, \
  271. ((uint8_t *)(p))[6] = ((uint64_t)(a) >> 8) & 0xFFU, \
  272. ((uint8_t *)(p))[7] = ((uint64_t)(a) >> 0) & 0xFFU
  273. //Swap a 16-bit integer
  274. #define SWAPINT16(x) ( \
  275. (((uint16_t)(x) & 0x00FFU) << 8) | \
  276. (((uint16_t)(x) & 0xFF00U) >> 8))
  277. //Swap a 32-bit integer
  278. #define SWAPINT32(x) ( \
  279. (((uint32_t)(x) & 0x000000FFUL) << 24) | \
  280. (((uint32_t)(x) & 0x0000FF00UL) << 8) | \
  281. (((uint32_t)(x) & 0x00FF0000UL) >> 8) | \
  282. (((uint32_t)(x) & 0xFF000000UL) >> 24))
  283. //Swap a 64-bit integer
  284. #define SWAPINT64(x) ( \
  285. (((uint64_t)(x) & 0x00000000000000FFULL) << 56) | \
  286. (((uint64_t)(x) & 0x000000000000FF00ULL) << 40) | \
  287. (((uint64_t)(x) & 0x0000000000FF0000ULL) << 24) | \
  288. (((uint64_t)(x) & 0x00000000FF000000ULL) << 8) | \
  289. (((uint64_t)(x) & 0x000000FF00000000ULL) >> 8) | \
  290. (((uint64_t)(x) & 0x0000FF0000000000ULL) >> 24) | \
  291. (((uint64_t)(x) & 0x00FF000000000000ULL) >> 40) | \
  292. (((uint64_t)(x) & 0xFF00000000000000ULL) >> 56))
  293. //Big-endian machine?
  294. #ifdef _CPU_BIG_ENDIAN
  295. //Host byte order to network byte order
  296. #define HTONS(value) (value)
  297. #define HTONL(value) (value)
  298. #define HTONLL(value) (value)
  299. #define htons(value) ((uint16_t) (value))
  300. #define htonl(value) ((uint32_t) (value))
  301. #define htonll(value) ((uint64_t) (value))
  302. //Network byte order to host byte order
  303. #define NTOHS(value) (value)
  304. #define NTOHL(value) (value)
  305. #define NTOHLL(value) (value)
  306. #define ntohs(value) ((uint16_t) (value))
  307. #define ntohl(value) ((uint32_t) (value))
  308. #define ntohll(value) ((uint64_t) (value))
  309. //Host byte order to little-endian byte order
  310. #define HTOLE16(value) SWAPINT16(value)
  311. #define HTOLE32(value) SWAPINT32(value)
  312. #define HTOLE64(value) SWAPINT64(value)
  313. #define htole16(value) swapInt16((uint16_t) (value))
  314. #define htole32(value) swapInt32((uint32_t) (value))
  315. #define htole64(value) swapInt64((uint64_t) (value))
  316. //Little-endian byte order to host byte order
  317. #define LETOH16(value) SWAPINT16(value)
  318. #define LETOH32(value) SWAPINT32(value)
  319. #define LETOH64(value) SWAPINT64(value)
  320. #define letoh16(value) swapInt16((uint16_t) (value))
  321. #define letoh32(value) swapInt32((uint32_t) (value))
  322. #define letoh64(value) swapInt64((uint64_t) (value))
  323. //Host byte order to big-endian byte order
  324. #define HTOBE16(value) (value)
  325. #define HTOBE32(value) (value)
  326. #define HTOBE64(value) (value)
  327. #define htobe16(value) ((uint16_t) (value))
  328. #define htobe32(value) ((uint32_t) (value))
  329. #define htobe64(value) ((uint64_t) (value))
  330. //Big-endian byte order to host byte order
  331. #define BETOH16(value) (value)
  332. #define BETOH32(value) (value)
  333. #define BETOH64(value) (value)
  334. #define betoh16(value) ((uint16_t) (value))
  335. #define betoh32(value) ((uint32_t) (value))
  336. #define betoh64(value) ((uint64_t) (value))
  337. //Little-endian machine?
  338. #else
  339. //Host byte order to network byte order
  340. #define HTONS(value) SWAPINT16(value)
  341. #define HTONL(value) SWAPINT32(value)
  342. #define HTONLL(value) SWAPINT64(value)
  343. #define htons(value) swapInt16((uint16_t) (value))
  344. #define htonl(value) swapInt32((uint32_t) (value))
  345. #define htonll(value) swapInt64((uint64_t) (value))
  346. //Network byte order to host byte order
  347. #define NTOHS(value) SWAPINT16(value)
  348. #define NTOHL(value) SWAPINT32(value)
  349. #define NTOHLL(value) SWAPINT64(value)
  350. #define ntohs(value) swapInt16((uint16_t) (value))
  351. #define ntohl(value) swapInt32((uint32_t) (value))
  352. #define ntohll(value) swapInt64((uint64_t) (value))
  353. //Host byte order to little-endian byte order
  354. #define HTOLE16(value) (value)
  355. #define HTOLE32(value) (value)
  356. #define HTOLE64(value) (value)
  357. #define htole16(value) ((uint16_t) (value))
  358. #define htole32(value) ((uint32_t) (value))
  359. #define htole64(value) ((uint64_t) (value))
  360. //Little-endian byte order to host byte order
  361. #define LETOH16(value) (value)
  362. #define LETOH32(value) (value)
  363. #define LETOH64(value) (value)
  364. #define letoh16(value) ((uint16_t) (value))
  365. #define letoh32(value) ((uint32_t) (value))
  366. #define letoh64(value) ((uint64_t) (value))
  367. //Host byte order to big-endian byte order
  368. #define HTOBE16(value) SWAPINT16(value)
  369. #define HTOBE32(value) SWAPINT32(value)
  370. #define HTOBE64(value) SWAPINT64(value)
  371. #define htobe16(value) swapInt16((uint16_t) (value))
  372. #define htobe32(value) swapInt32((uint32_t) (value))
  373. #define htobe64(value) swapInt64((uint64_t) (value))
  374. //Big-endian byte order to host byte order
  375. #define BETOH16(value) SWAPINT16(value)
  376. #define BETOH32(value) SWAPINT32(value)
  377. #define BETOH64(value) SWAPINT64(value)
  378. #define betoh16(value) swapInt16((uint16_t) (value))
  379. #define betoh32(value) swapInt32((uint32_t) (value))
  380. #define betoh64(value) swapInt64((uint64_t) (value))
  381. #endif
  382. //C++ guard
  383. #ifdef __cplusplus
  384. extern "C" {
  385. #endif
  386. //Byte order conversion functions
  387. uint16_t swapInt16(uint16_t value);
  388. uint32_t swapInt32(uint32_t value);
  389. uint64_t swapInt64(uint64_t value);
  390. //Bit reversal functions
  391. uint8_t reverseInt4(uint8_t value);
  392. uint8_t reverseInt8(uint8_t value);
  393. uint16_t reverseInt16(uint16_t value);
  394. uint32_t reverseInt32(uint32_t value);
  395. uint64_t reverseInt64(uint64_t value);
  396. //C++ guard
  397. #ifdef __cplusplus
  398. }
  399. #endif
  400. #endif