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/Support/Host.h"
18 #include "llvm/Support/SwapByteOrder.h"
19 #include "llvm/Support/type_traits.h"
24 enum endianness {big, little};
25 enum alignment {unaligned, aligned};
29 template<typename value_type, alignment align>
30 struct alignment_access_helper;
32 template<typename value_type>
33 struct alignment_access_helper<value_type, aligned>
38 // Provides unaligned loads and stores.
41 template<typename value_type>
42 struct alignment_access_helper<value_type, unaligned>
48 } // end namespace detail
51 template<typename value_type, alignment align>
52 inline value_type read_le(const void *memory) {
54 reinterpret_cast<const detail::alignment_access_helper
55 <value_type, align> *>(memory)->val;
56 if (sys::isBigEndianHost())
57 return sys::SwapByteOrder(t);
61 template<typename value_type, alignment align>
62 inline void write_le(void *memory, value_type value) {
63 if (sys::isBigEndianHost())
64 value = sys::SwapByteOrder(value);
65 reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
66 (memory)->val = value;
69 template<typename value_type, alignment align>
70 inline value_type read_be(const void *memory) {
72 reinterpret_cast<const detail::alignment_access_helper
73 <value_type, align> *>(memory)->val;
74 if (sys::isLittleEndianHost())
75 return sys::SwapByteOrder(t);
79 template<typename value_type, alignment align>
80 inline void write_be(void *memory, value_type value) {
81 if (sys::isLittleEndianHost())
82 value = sys::SwapByteOrder(value);
83 reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
84 (memory)->val = value;
90 template<typename value_type,
93 class packed_endian_specific_integral;
95 template<typename value_type>
96 class packed_endian_specific_integral<value_type, little, unaligned> {
98 operator value_type() const {
99 return endian::read_le<value_type, unaligned>(Value);
101 void operator=(value_type newValue) {
102 endian::write_le<value_type, unaligned>((void *)&Value, newValue);
105 uint8_t Value[sizeof(value_type)];
108 template<typename value_type>
109 class packed_endian_specific_integral<value_type, big, unaligned> {
111 operator value_type() const {
112 return endian::read_be<value_type, unaligned>(Value);
114 void operator=(value_type newValue) {
115 endian::write_be<value_type, unaligned>((void *)&Value, newValue);
118 uint8_t Value[sizeof(value_type)];
121 template<typename value_type>
122 class packed_endian_specific_integral<value_type, little, aligned> {
124 operator value_type() const {
125 return endian::read_le<value_type, aligned>(&Value);
127 void operator=(value_type newValue) {
128 endian::write_le<value_type, aligned>((void *)&Value, newValue);
134 template<typename value_type>
135 class packed_endian_specific_integral<value_type, big, aligned> {
137 operator value_type() const {
138 return endian::read_be<value_type, aligned>(&Value);
140 void operator=(value_type newValue) {
141 endian::write_be<value_type, aligned>((void *)&Value, newValue);
147 } // end namespace detail
149 typedef detail::packed_endian_specific_integral
150 <uint8_t, little, unaligned> ulittle8_t;
151 typedef detail::packed_endian_specific_integral
152 <uint16_t, little, unaligned> ulittle16_t;
153 typedef detail::packed_endian_specific_integral
154 <uint32_t, little, unaligned> ulittle32_t;
155 typedef detail::packed_endian_specific_integral
156 <uint64_t, little, unaligned> ulittle64_t;
158 typedef detail::packed_endian_specific_integral
159 <int8_t, little, unaligned> little8_t;
160 typedef detail::packed_endian_specific_integral
161 <int16_t, little, unaligned> little16_t;
162 typedef detail::packed_endian_specific_integral
163 <int32_t, little, unaligned> little32_t;
164 typedef detail::packed_endian_specific_integral
165 <int64_t, little, unaligned> little64_t;
167 typedef detail::packed_endian_specific_integral
168 <uint8_t, little, aligned> aligned_ulittle8_t;
169 typedef detail::packed_endian_specific_integral
170 <uint16_t, little, aligned> aligned_ulittle16_t;
171 typedef detail::packed_endian_specific_integral
172 <uint32_t, little, aligned> aligned_ulittle32_t;
173 typedef detail::packed_endian_specific_integral
174 <uint64_t, little, aligned> aligned_ulittle64_t;
176 typedef detail::packed_endian_specific_integral
177 <int8_t, little, aligned> aligned_little8_t;
178 typedef detail::packed_endian_specific_integral
179 <int16_t, little, aligned> aligned_little16_t;
180 typedef detail::packed_endian_specific_integral
181 <int32_t, little, aligned> aligned_little32_t;
182 typedef detail::packed_endian_specific_integral
183 <int64_t, little, aligned> aligned_little64_t;
185 typedef detail::packed_endian_specific_integral
186 <uint8_t, big, unaligned> ubig8_t;
187 typedef detail::packed_endian_specific_integral
188 <uint16_t, big, unaligned> ubig16_t;
189 typedef detail::packed_endian_specific_integral
190 <uint32_t, big, unaligned> ubig32_t;
191 typedef detail::packed_endian_specific_integral
192 <uint64_t, big, unaligned> ubig64_t;
194 typedef detail::packed_endian_specific_integral
195 <int8_t, big, unaligned> big8_t;
196 typedef detail::packed_endian_specific_integral
197 <int16_t, big, unaligned> big16_t;
198 typedef detail::packed_endian_specific_integral
199 <int32_t, big, unaligned> big32_t;
200 typedef detail::packed_endian_specific_integral
201 <int64_t, big, unaligned> big64_t;
203 typedef detail::packed_endian_specific_integral
204 <uint8_t, big, aligned> aligned_ubig8_t;
205 typedef detail::packed_endian_specific_integral
206 <uint16_t, big, aligned> aligned_ubig16_t;
207 typedef detail::packed_endian_specific_integral
208 <uint32_t, big, aligned> aligned_ubig32_t;
209 typedef detail::packed_endian_specific_integral
210 <uint64_t, big, aligned> aligned_ubig64_t;
212 typedef detail::packed_endian_specific_integral
213 <int8_t, big, aligned> aligned_big8_t;
214 typedef detail::packed_endian_specific_integral
215 <int16_t, big, aligned> aligned_big16_t;
216 typedef detail::packed_endian_specific_integral
217 <int32_t, big, aligned> aligned_big32_t;
218 typedef detail::packed_endian_specific_integral
219 <int64_t, big, aligned> aligned_big64_t;
221 } // end namespace llvm
222 } // end namespace support