SwapByteOrder.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. //===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file declares generic and optimized functions to swap the byte order of
  11. // an integral type.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_SUPPORT_SWAPBYTEORDER_H
  15. #define LLVM_SUPPORT_SWAPBYTEORDER_H
  16. #include "llvm/Support/Compiler.h"
  17. #include "llvm/Support/DataTypes.h"
  18. #include <cstddef>
  19. #include <limits>
  20. namespace llvm {
  21. namespace sys {
  22. /// SwapByteOrder_16 - This function returns a byte-swapped representation of
  23. /// the 16-bit argument.
  24. inline uint16_t SwapByteOrder_16(uint16_t value) {
  25. #if defined(_MSC_VER) && !defined(_DEBUG)
  26. // The DLL version of the runtime lacks these functions (bug!?), but in a
  27. // release build they're replaced with BSWAP instructions anyway.
  28. return _byteswap_ushort(value);
  29. #else
  30. uint16_t Hi = value << 8;
  31. uint16_t Lo = value >> 8;
  32. return Hi | Lo;
  33. #endif
  34. }
  35. /// SwapByteOrder_32 - This function returns a byte-swapped representation of
  36. /// the 32-bit argument.
  37. inline uint32_t SwapByteOrder_32(uint32_t value) {
  38. #if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC))
  39. return __builtin_bswap32(value);
  40. #elif defined(_MSC_VER) && !defined(_DEBUG)
  41. return _byteswap_ulong(value);
  42. #else
  43. uint32_t Byte0 = value & 0x000000FF;
  44. uint32_t Byte1 = value & 0x0000FF00;
  45. uint32_t Byte2 = value & 0x00FF0000;
  46. uint32_t Byte3 = value & 0xFF000000;
  47. return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
  48. #endif
  49. }
  50. /// SwapByteOrder_64 - This function returns a byte-swapped representation of
  51. /// the 64-bit argument.
  52. inline uint64_t SwapByteOrder_64(uint64_t value) {
  53. #if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC))
  54. return __builtin_bswap64(value);
  55. #elif defined(_MSC_VER) && !defined(_DEBUG)
  56. return _byteswap_uint64(value);
  57. #else
  58. uint64_t Hi = SwapByteOrder_32(uint32_t(value));
  59. uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
  60. return (Hi << 32) | Lo;
  61. #endif
  62. }
  63. inline unsigned char getSwappedBytes(unsigned char C) { return C; }
  64. inline signed char getSwappedBytes(signed char C) { return C; }
  65. inline char getSwappedBytes(char C) { return C; }
  66. inline unsigned short getSwappedBytes(unsigned short C) { return SwapByteOrder_16(C); }
  67. inline signed short getSwappedBytes( signed short C) { return SwapByteOrder_16(C); }
  68. inline unsigned int getSwappedBytes(unsigned int C) { return SwapByteOrder_32(C); }
  69. inline signed int getSwappedBytes( signed int C) { return SwapByteOrder_32(C); }
  70. #if __LONG_MAX__ == __INT_MAX__
  71. inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_32(C); }
  72. inline signed long getSwappedBytes( signed long C) { return SwapByteOrder_32(C); }
  73. #elif __LONG_MAX__ == __LONG_LONG_MAX__
  74. inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_64(C); }
  75. inline signed long getSwappedBytes( signed long C) { return SwapByteOrder_64(C); }
  76. #else
  77. #error "Unknown long size!"
  78. #endif
  79. inline unsigned long long getSwappedBytes(unsigned long long C) {
  80. return SwapByteOrder_64(C);
  81. }
  82. inline signed long long getSwappedBytes(signed long long C) {
  83. return SwapByteOrder_64(C);
  84. }
  85. inline float getSwappedBytes(float C) {
  86. union {
  87. uint32_t i;
  88. float f;
  89. } in, out;
  90. in.f = C;
  91. out.i = SwapByteOrder_32(in.i);
  92. return out.f;
  93. }
  94. inline double getSwappedBytes(double C) {
  95. union {
  96. uint64_t i;
  97. double d;
  98. } in, out;
  99. in.d = C;
  100. out.i = SwapByteOrder_64(in.i);
  101. return out.d;
  102. }
  103. template<typename T>
  104. inline void swapByteOrder(T &Value) {
  105. Value = getSwappedBytes(Value);
  106. }
  107. } // end namespace sys
  108. } // end namespace llvm
  109. #endif