llvm.org GIT mirror llvm / 5e0b2bf
Support: Add Endian.h git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117057 91177308-0d34-0410-b5e6-96231b3b80d8 Michael J. Spencer 9 years ago
5 changed file(s) with 308 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
22 include(CheckSymbolExists)
33 include(CheckFunctionExists)
44 include(CheckCXXSourceCompiles)
5 include(TestBigEndian)
56
67 if( UNIX AND NOT BEOS )
78 # Used by check_symbol_exists:
256257 endif()
257258 endif()
258259
260 test_big_endian(LLVM_IS_TARGET_BIG_ENDIAN)
261
259262 if( ENABLE_THREADS )
260263 message(STATUS "Threads enabled.")
261264 else( ENABLE_THREADS )
504504
505505 /* Define if this is Win32ish platform */
506506 #cmakedefine LLVM_ON_WIN32 ${LLVM_ON_WIN32}
507
508 /* Define if this is targeting a big endian system */
509 #cmakedefine LLVM_IS_TARGET_BIG_ENDIAN ${LLVM_IS_TARGET_BIG_ENDIAN}
507510
508511 /* Added by Kevin -- Maximum path length */
509512 #cmakedefine MAXPATHLEN ${MAXPATHLEN}
0 //===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares generic functions to read and write endian specific data.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_SUPPORT_ENDIAN_H
14 #define LLVM_SUPPORT_ENDIAN_H
15
16 #include "llvm/Config/config.h"
17 #include "llvm/System/SwapByteOrder.h"
18 #include "llvm/Support/type_traits.h"
19
20 namespace llvm {
21 namespace support {
22
23 enum endianness {big, little};
24 enum alignment {unaligned, aligned};
25
26 template
27 static typename enable_if_c::type
28 SwapByteOrderIfDifferent(value_type value) {
29 // Target endianess is the same as the host. Just pass the value through.
30 return value;
31 }
32
33 template
34 static typename enable_if_c::type
35 SwapByteOrderIfDifferent(value_type value) {
36 return sys::SwapByteOrder(value);
37 }
38
39 namespace detail {
40
41 template
42 struct alignment_access_helper;
43
44 template
45 struct alignment_access_helper
46 {
47 value_type val;
48 };
49
50 // Provides unaligned loads and stores.
51 #pragma pack(push)
52 #pragma pack(1)
53 template
54 struct alignment_access_helper
55 {
56 value_type val;
57 };
58 #pragma pack(pop)
59
60 } // end namespace detail
61
62 #if defined(LLVM_IS_TARGET_BIG_ENDIAN) \
63 || defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN__)
64 static const endianness host_endianness = big;
65 #else
66 static const endianness host_endianness = little;
67 #endif
68
69 struct endian {
70 template
71 static value_type read_le(const void *memory) {
72 return SwapByteOrderIfDifferent(
73 reinterpret_cast
74 *>(memory)->val);
75 }
76
77 template
78 static void write_le(void *memory, value_type value) {
79 reinterpret_cast *>
80 (memory)->val =
81 SwapByteOrderIfDifferent< value_type
82 , host_endianness
83 , little>(value);
84 }
85
86 template
87 static value_type read_be(const void *memory) {
88 return SwapByteOrderIfDifferent(
89 reinterpret_cast
90 *>(memory)->val);
91 }
92
93 template
94 static void write_be(void *memory, value_type value) {
95 reinterpret_cast
96 *>(memory)->val =
97 SwapByteOrderIfDifferent< value_type
98 , host_endianness
99 , big>(value);
100 }
101 };
102
103 namespace detail {
104
105 template
106 endianness target_endianness,
107 alignment target_alignment>
108 class packed_endian_specific_integral;
109
110 template
111 class packed_endian_specific_integral {
112 public:
113 operator value_type() const {
114 return endian::read_le(Value);
115 }
116 private:
117 uint8_t Value[sizeof(value_type)];
118 };
119
120 template
121 class packed_endian_specific_integral {
122 public:
123 operator value_type() const {
124 return endian::read_be(Value);
125 }
126 private:
127 uint8_t Value[sizeof(value_type)];
128 };
129
130 template
131 class packed_endian_specific_integral {
132 public:
133 operator value_type() const {
134 return endian::read_le(&Value);
135 }
136 private:
137 value_type Value;
138 };
139
140 template
141 class packed_endian_specific_integral {
142 public:
143 operator value_type() const {
144 return endian::read_be(&Value);
145 }
146 private:
147 value_type Value;
148 };
149
150 } // end namespace detail
151
152 typedef detail::packed_endian_specific_integral
153 ulittle8_t;
154 typedef detail::packed_endian_specific_integral
155 ulittle16_t;
156 typedef detail::packed_endian_specific_integral
157 ulittle32_t;
158 typedef detail::packed_endian_specific_integral
159 ulittle64_t;
160
161 typedef detail::packed_endian_specific_integral
162 little8_t;
163 typedef detail::packed_endian_specific_integral
164 little16_t;
165 typedef detail::packed_endian_specific_integral
166 little32_t;
167 typedef detail::packed_endian_specific_integral
168 little64_t;
169
170 typedef detail::packed_endian_specific_integral
171 aligned_ulittle8_t;
172 typedef detail::packed_endian_specific_integral
173 aligned_ulittle16_t;
174 typedef detail::packed_endian_specific_integral
175 aligned_ulittle32_t;
176 typedef detail::packed_endian_specific_integral
177 aligned_ulittle64_t;
178
179 typedef detail::packed_endian_specific_integral
180 aligned_little8_t;
181 typedef detail::packed_endian_specific_integral
182 aligned_little16_t;
183 typedef detail::packed_endian_specific_integral
184 aligned_little32_t;
185 typedef detail::packed_endian_specific_integral
186 aligned_little64_t;
187
188 typedef detail::packed_endian_specific_integral
189 ubig8_t;
190 typedef detail::packed_endian_specific_integral
191 ubig16_t;
192 typedef detail::packed_endian_specific_integral
193 ubig32_t;
194 typedef detail::packed_endian_specific_integral
195 ubig64_t;
196
197 typedef detail::packed_endian_specific_integral
198 big8_t;
199 typedef detail::packed_endian_specific_integral
200 big16_t;
201 typedef detail::packed_endian_specific_integral
202 big32_t;
203 typedef detail::packed_endian_specific_integral
204 big64_t;
205
206 typedef detail::packed_endian_specific_integral
207 aligned_ubig8_t;
208 typedef detail::packed_endian_specific_integral
209 aligned_ubig16_t;
210 typedef detail::packed_endian_specific_integral
211 aligned_ubig32_t;
212 typedef detail::packed_endian_specific_integral
213 aligned_ubig64_t;
214
215 typedef detail::packed_endian_specific_integral
216 aligned_big8_t;
217 typedef detail::packed_endian_specific_integral
218 aligned_big16_t;
219 typedef detail::packed_endian_specific_integral
220 aligned_big32_t;
221 typedef detail::packed_endian_specific_integral
222 aligned_big64_t;
223
224 } // end namespace llvm
225 } // end namespace support
226
227 #endif
9191 Support/Casting.cpp
9292 Support/CommandLineTest.cpp
9393 Support/ConstantRangeTest.cpp
94 Support/EndianTest.cpp
9495 Support/LeakDetectorTest.cpp
9596 Support/MathExtrasTest.cpp
9697 Support/raw_ostream_test.cpp
9798 Support/RegexTest.cpp
99 Support/SwapByteOrderTest.cpp
98100 Support/System.cpp
99 Support/SwapByteOrderTest.cpp
100101 Support/TypeBuilderTest.cpp
101102 Support/ValueHandleTest.cpp
102103 )
0 //===- unittests/Support/EndianTest.cpp - Endian.h tests ------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "gtest/gtest.h"
10 #include "llvm/Support/Endian.h"
11 #include "llvm/System/DataTypes.h"
12 #include
13 #include
14 using namespace llvm;
15 using namespace support;
16
17 #undef max
18
19 namespace {
20
21 TEST(Endian, Read) {
22 // These are 5 bytes so we can be sure at least one of the reads is unaligned.
23 unsigned char big[] = {0x00, 0x01, 0x02, 0x03, 0x04};
24 unsigned char little[] = {0x00, 0x04, 0x03, 0x02, 0x01};
25 int32_t BigAsHost = 0x00010203;
26 EXPECT_EQ(BigAsHost, (endian::read_be(big)));
27 int32_t LittleAsHost = 0x02030400;
28 EXPECT_EQ(LittleAsHost, (endian::read_le(little)));
29
30 EXPECT_EQ((endian::read_be(big + 1)),
31 (endian::read_le(little + 1)));
32 }
33
34 TEST(Endian, Write) {
35 unsigned char data[5];
36 endian::write_be(data, -1362446643);
37 EXPECT_EQ(data[0], 0xAE);
38 EXPECT_EQ(data[1], 0xCA);
39 EXPECT_EQ(data[2], 0xB6);
40 EXPECT_EQ(data[3], 0xCD);
41 endian::write_be(data + 1, -1362446643);
42 EXPECT_EQ(data[1], 0xAE);
43 EXPECT_EQ(data[2], 0xCA);
44 EXPECT_EQ(data[3], 0xB6);
45 EXPECT_EQ(data[4], 0xCD);
46
47 endian::write_le(data, -1362446643);
48 EXPECT_EQ(data[0], 0xCD);
49 EXPECT_EQ(data[1], 0xB6);
50 EXPECT_EQ(data[2], 0xCA);
51 EXPECT_EQ(data[3], 0xAE);
52 endian::write_le(data + 1, -1362446643);
53 EXPECT_EQ(data[1], 0xCD);
54 EXPECT_EQ(data[2], 0xB6);
55 EXPECT_EQ(data[3], 0xCA);
56 EXPECT_EQ(data[4], 0xAE);
57 }
58
59 TEST(Endian, PackedEndianSpecificIntegral) {
60 // These are 5 bytes so we can be sure at least one of the reads is unaligned.
61 unsigned char big[] = {0x00, 0x01, 0x02, 0x03, 0x04};
62 unsigned char little[] = {0x00, 0x04, 0x03, 0x02, 0x01};
63 big32_t *big_val =
64 reinterpret_cast(big + 1);
65 little32_t *little_val =
66 reinterpret_cast(little + 1);
67
68 EXPECT_EQ(*big_val, *little_val);
69 }
70
71 }