]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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 | ||
970d7e83 LB |
15 | #ifndef LLVM_SUPPORT_SWAPBYTEORDER_H |
16 | #define LLVM_SUPPORT_SWAPBYTEORDER_H | |
223e47cc | 17 | |
85aaf69f | 18 | #include "llvm/Support/Compiler.h" |
223e47cc LB |
19 | #include "llvm/Support/DataTypes.h" |
20 | #include <cstddef> | |
21 | #include <limits> | |
22 | ||
23 | namespace llvm { | |
24 | namespace sys { | |
25 | ||
26 | /// SwapByteOrder_16 - This function returns a byte-swapped representation of | |
27 | /// the 16-bit argument. | |
28 | inline uint16_t SwapByteOrder_16(uint16_t value) { | |
29 | #if defined(_MSC_VER) && !defined(_DEBUG) | |
30 | // The DLL version of the runtime lacks these functions (bug!?), but in a | |
31 | // release build they're replaced with BSWAP instructions anyway. | |
32 | return _byteswap_ushort(value); | |
33 | #else | |
34 | uint16_t Hi = value << 8; | |
35 | uint16_t Lo = value >> 8; | |
36 | return Hi | Lo; | |
37 | #endif | |
38 | } | |
39 | ||
40 | /// SwapByteOrder_32 - This function returns a byte-swapped representation of | |
41 | /// the 32-bit argument. | |
42 | inline uint32_t SwapByteOrder_32(uint32_t value) { | |
85aaf69f | 43 | #if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC)) |
223e47cc LB |
44 | return __builtin_bswap32(value); |
45 | #elif defined(_MSC_VER) && !defined(_DEBUG) | |
46 | return _byteswap_ulong(value); | |
47 | #else | |
48 | uint32_t Byte0 = value & 0x000000FF; | |
49 | uint32_t Byte1 = value & 0x0000FF00; | |
50 | uint32_t Byte2 = value & 0x00FF0000; | |
51 | uint32_t Byte3 = value & 0xFF000000; | |
52 | return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24); | |
53 | #endif | |
54 | } | |
55 | ||
56 | /// SwapByteOrder_64 - This function returns a byte-swapped representation of | |
57 | /// the 64-bit argument. | |
58 | inline uint64_t SwapByteOrder_64(uint64_t value) { | |
85aaf69f | 59 | #if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC)) |
223e47cc LB |
60 | return __builtin_bswap64(value); |
61 | #elif defined(_MSC_VER) && !defined(_DEBUG) | |
62 | return _byteswap_uint64(value); | |
63 | #else | |
64 | uint64_t Hi = SwapByteOrder_32(uint32_t(value)); | |
65 | uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32)); | |
66 | return (Hi << 32) | Lo; | |
67 | #endif | |
68 | } | |
69 | ||
1a4d82fc JJ |
70 | inline unsigned char getSwappedBytes(unsigned char C) { return C; } |
71 | inline signed char getSwappedBytes(signed char C) { return C; } | |
72 | inline char getSwappedBytes(char C) { return C; } | |
223e47cc | 73 | |
1a4d82fc JJ |
74 | inline unsigned short getSwappedBytes(unsigned short C) { return SwapByteOrder_16(C); } |
75 | inline signed short getSwappedBytes( signed short C) { return SwapByteOrder_16(C); } | |
223e47cc | 76 | |
1a4d82fc JJ |
77 | inline unsigned int getSwappedBytes(unsigned int C) { return SwapByteOrder_32(C); } |
78 | inline signed int getSwappedBytes( signed int C) { return SwapByteOrder_32(C); } | |
223e47cc LB |
79 | |
80 | #if __LONG_MAX__ == __INT_MAX__ | |
1a4d82fc JJ |
81 | inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_32(C); } |
82 | inline signed long getSwappedBytes( signed long C) { return SwapByteOrder_32(C); } | |
223e47cc | 83 | #elif __LONG_MAX__ == __LONG_LONG_MAX__ |
1a4d82fc JJ |
84 | inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_64(C); } |
85 | inline signed long getSwappedBytes( signed long C) { return SwapByteOrder_64(C); } | |
223e47cc LB |
86 | #else |
87 | #error "Unknown long size!" | |
88 | #endif | |
89 | ||
1a4d82fc | 90 | inline unsigned long long getSwappedBytes(unsigned long long C) { |
223e47cc LB |
91 | return SwapByteOrder_64(C); |
92 | } | |
1a4d82fc | 93 | inline signed long long getSwappedBytes(signed long long C) { |
223e47cc LB |
94 | return SwapByteOrder_64(C); |
95 | } | |
96 | ||
1a4d82fc JJ |
97 | template<typename T> |
98 | inline void swapByteOrder(T &Value) { | |
99 | Value = getSwappedBytes(Value); | |
100 | } | |
101 | ||
223e47cc LB |
102 | } // end namespace sys |
103 | } // end namespace llvm | |
104 | ||
105 | #endif |