Line data Source code
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 :
15 : #ifndef LLVM_SUPPORT_SWAPBYTEORDER_H
16 : #define LLVM_SUPPORT_SWAPBYTEORDER_H
17 :
18 : #include "llvm/Support/Compiler.h"
19 : #include "llvm/Support/DataTypes.h"
20 : #include <cstddef>
21 : #if defined(_MSC_VER) && !defined(_DEBUG)
22 : #include <stdlib.h>
23 : #endif
24 :
25 : namespace llvm {
26 : namespace sys {
27 :
28 : /// SwapByteOrder_16 - This function returns a byte-swapped representation of
29 : /// the 16-bit argument.
30 : inline uint16_t SwapByteOrder_16(uint16_t value) {
31 : #if defined(_MSC_VER) && !defined(_DEBUG)
32 : // The DLL version of the runtime lacks these functions (bug!?), but in a
33 : // release build they're replaced with BSWAP instructions anyway.
34 : return _byteswap_ushort(value);
35 : #else
36 15550519 : uint16_t Hi = value << 8;
37 15574227 : uint16_t Lo = value >> 8;
38 15570091 : return Hi | Lo;
39 : #endif
40 : }
41 :
42 : /// SwapByteOrder_32 - This function returns a byte-swapped representation of
43 : /// the 32-bit argument.
44 : inline uint32_t SwapByteOrder_32(uint32_t value) {
45 : #if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC))
46 2437464 : return __builtin_bswap32(value);
47 : #elif defined(_MSC_VER) && !defined(_DEBUG)
48 : return _byteswap_ulong(value);
49 : #else
50 : uint32_t Byte0 = value & 0x000000FF;
51 : uint32_t Byte1 = value & 0x0000FF00;
52 : uint32_t Byte2 = value & 0x00FF0000;
53 : uint32_t Byte3 = value & 0xFF000000;
54 : return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
55 : #endif
56 : }
57 :
58 : /// SwapByteOrder_64 - This function returns a byte-swapped representation of
59 : /// the 64-bit argument.
60 : inline uint64_t SwapByteOrder_64(uint64_t value) {
61 : #if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC))
62 222712 : return __builtin_bswap64(value);
63 : #elif defined(_MSC_VER) && !defined(_DEBUG)
64 : return _byteswap_uint64(value);
65 : #else
66 : uint64_t Hi = SwapByteOrder_32(uint32_t(value));
67 : uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
68 : return (Hi << 32) | Lo;
69 : #endif
70 : }
71 :
72 : inline unsigned char getSwappedBytes(unsigned char C) { return C; }
73 : inline signed char getSwappedBytes(signed char C) { return C; }
74 : inline char getSwappedBytes(char C) { return C; }
75 :
76 : inline unsigned short getSwappedBytes(unsigned short C) { return SwapByteOrder_16(C); }
77 55 : inline signed short getSwappedBytes( signed short C) { return SwapByteOrder_16(C); }
78 :
79 : inline unsigned int getSwappedBytes(unsigned int C) { return SwapByteOrder_32(C); }
80 1177 : inline signed int getSwappedBytes( signed int C) { return SwapByteOrder_32(C); }
81 :
82 : #if __LONG_MAX__ == __INT_MAX__
83 : inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_32(C); }
84 : inline signed long getSwappedBytes( signed long C) { return SwapByteOrder_32(C); }
85 : #elif __LONG_MAX__ == __LONG_LONG_MAX__
86 : inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_64(C); }
87 11534 : inline signed long getSwappedBytes( signed long C) { return SwapByteOrder_64(C); }
88 : #else
89 : #error "Unknown long size!"
90 : #endif
91 :
92 : inline unsigned long long getSwappedBytes(unsigned long long C) {
93 : return SwapByteOrder_64(C);
94 : }
95 : inline signed long long getSwappedBytes(signed long long C) {
96 : return SwapByteOrder_64(C);
97 : }
98 :
99 : inline float getSwappedBytes(float C) {
100 : union {
101 : uint32_t i;
102 : float f;
103 : } in, out;
104 : in.f = C;
105 : out.i = SwapByteOrder_32(in.i);
106 0 : return out.f;
107 : }
108 :
109 : inline double getSwappedBytes(double C) {
110 : union {
111 : uint64_t i;
112 : double d;
113 : } in, out;
114 : in.d = C;
115 : out.i = SwapByteOrder_64(in.i);
116 0 : return out.d;
117 : }
118 :
119 : template<typename T>
120 0 : inline void swapByteOrder(T &Value) {
121 555 : Value = getSwappedBytes(Value);
122 0 : }
123 0 :
124 : } // end namespace sys
125 0 : } // end namespace llvm
126 0 :
127 : #endif
|