1 //===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares generic functions to read and write endian specific data.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_SUPPORT_ENDIAN_H
15 #define LLVM_SUPPORT_ENDIAN_H
17 #include "llvm/Config/config.h"
18 #include "llvm/System/SwapByteOrder.h"
19 #include "llvm/Support/type_traits.h"
24 enum endianness {big, little};
25 enum alignment {unaligned, aligned};
27 template<typename value_type, int host, int target>
28 static typename enable_if_c<host == target, value_type>::type
29 SwapByteOrderIfDifferent(value_type value) {
30 // Target endianess is the same as the host. Just pass the value through.
34 template<typename value_type, int host, int target>
35 static typename enable_if_c<host != target, value_type>::type
36 SwapByteOrderIfDifferent(value_type value) {
37 return sys::SwapByteOrder<value_type>(value);
42 template<typename value_type, alignment align>
43 struct alignment_access_helper;
45 template<typename value_type>
46 struct alignment_access_helper<value_type, aligned>
51 // Provides unaligned loads and stores.
54 template<typename value_type>
55 struct alignment_access_helper<value_type, unaligned>
61 } // end namespace detail
63 #if defined(LLVM_IS_HOST_BIG_ENDIAN) \
64 || defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN__)
65 static const endianness host_endianness = big;
67 static const endianness host_endianness = little;
71 template<typename value_type, alignment align>
72 static value_type read_le(const void *memory) {
73 return SwapByteOrderIfDifferent<value_type, host_endianness, little>(
74 reinterpret_cast<const detail::alignment_access_helper
75 <value_type, align> *>(memory)->val);
78 template<typename value_type, alignment align>
79 static void write_le(void *memory, value_type value) {
80 reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
82 SwapByteOrderIfDifferent< value_type
87 template<typename value_type, alignment align>
88 static value_type read_be(const void *memory) {
89 return SwapByteOrderIfDifferent<value_type, host_endianness, big>(
90 reinterpret_cast<const detail::alignment_access_helper
91 <value_type, align> *>(memory)->val);
94 template<typename value_type, alignment align>
95 static void write_be(void *memory, value_type value) {
96 reinterpret_cast<detail::alignment_access_helper
97 <value_type, align> *>(memory)->val =
98 SwapByteOrderIfDifferent< value_type
106 template<typename value_type,
107 endianness target_endianness,
108 alignment target_alignment>
109 class packed_endian_specific_integral;
111 template<typename value_type>
112 class packed_endian_specific_integral<value_type, little, unaligned> {
114 operator value_type() const {
115 return endian::read_le<value_type, unaligned>(Value);
118 uint8_t Value[sizeof(value_type)];
121 template<typename value_type>
122 class packed_endian_specific_integral<value_type, big, unaligned> {
124 operator value_type() const {
125 return endian::read_be<value_type, unaligned>(Value);
128 uint8_t Value[sizeof(value_type)];
131 template<typename value_type>
132 class packed_endian_specific_integral<value_type, little, aligned> {
134 operator value_type() const {
135 return endian::read_le<value_type, aligned>(&Value);
141 template<typename value_type>
142 class packed_endian_specific_integral<value_type, big, aligned> {
144 operator value_type() const {
145 return endian::read_be<value_type, aligned>(&Value);
151 } // end namespace detail
153 typedef detail::packed_endian_specific_integral
154 <uint8_t, little, unaligned> ulittle8_t;
155 typedef detail::packed_endian_specific_integral
156 <uint16_t, little, unaligned> ulittle16_t;
157 typedef detail::packed_endian_specific_integral
158 <uint32_t, little, unaligned> ulittle32_t;
159 typedef detail::packed_endian_specific_integral
160 <uint64_t, little, unaligned> ulittle64_t;
162 typedef detail::packed_endian_specific_integral
163 <int8_t, little, unaligned> little8_t;
164 typedef detail::packed_endian_specific_integral
165 <int16_t, little, unaligned> little16_t;
166 typedef detail::packed_endian_specific_integral
167 <int32_t, little, unaligned> little32_t;
168 typedef detail::packed_endian_specific_integral
169 <int64_t, little, unaligned> little64_t;
171 typedef detail::packed_endian_specific_integral
172 <uint8_t, little, aligned> aligned_ulittle8_t;
173 typedef detail::packed_endian_specific_integral
174 <uint16_t, little, aligned> aligned_ulittle16_t;
175 typedef detail::packed_endian_specific_integral
176 <uint32_t, little, aligned> aligned_ulittle32_t;
177 typedef detail::packed_endian_specific_integral
178 <uint64_t, little, aligned> aligned_ulittle64_t;
180 typedef detail::packed_endian_specific_integral
181 <int8_t, little, aligned> aligned_little8_t;
182 typedef detail::packed_endian_specific_integral
183 <int16_t, little, aligned> aligned_little16_t;
184 typedef detail::packed_endian_specific_integral
185 <int32_t, little, aligned> aligned_little32_t;
186 typedef detail::packed_endian_specific_integral
187 <int64_t, little, aligned> aligned_little64_t;
189 typedef detail::packed_endian_specific_integral
190 <uint8_t, big, unaligned> ubig8_t;
191 typedef detail::packed_endian_specific_integral
192 <uint16_t, big, unaligned> ubig16_t;
193 typedef detail::packed_endian_specific_integral
194 <uint32_t, big, unaligned> ubig32_t;
195 typedef detail::packed_endian_specific_integral
196 <uint64_t, big, unaligned> ubig64_t;
198 typedef detail::packed_endian_specific_integral
199 <int8_t, big, unaligned> big8_t;
200 typedef detail::packed_endian_specific_integral
201 <int16_t, big, unaligned> big16_t;
202 typedef detail::packed_endian_specific_integral
203 <int32_t, big, unaligned> big32_t;
204 typedef detail::packed_endian_specific_integral
205 <int64_t, big, unaligned> big64_t;
207 typedef detail::packed_endian_specific_integral
208 <uint8_t, big, aligned> aligned_ubig8_t;
209 typedef detail::packed_endian_specific_integral
210 <uint16_t, big, aligned> aligned_ubig16_t;
211 typedef detail::packed_endian_specific_integral
212 <uint32_t, big, aligned> aligned_ubig32_t;
213 typedef detail::packed_endian_specific_integral
214 <uint64_t, big, aligned> aligned_ubig64_t;
216 typedef detail::packed_endian_specific_integral
217 <int8_t, big, aligned> aligned_big8_t;
218 typedef detail::packed_endian_specific_integral
219 <int16_t, big, aligned> aligned_big16_t;
220 typedef detail::packed_endian_specific_integral
221 <int32_t, big, aligned> aligned_big32_t;
222 typedef detail::packed_endian_specific_integral
223 <int64_t, big, aligned> aligned_big64_t;
225 } // end namespace llvm
226 } // end namespace support