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 static 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 static 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 static 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 static 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);
102 uint8_t Value[sizeof(value_type)];
105 template<typename value_type>
106 class packed_endian_specific_integral<value_type, big, unaligned> {
108 operator value_type() const {
109 return endian::read_be<value_type, unaligned>(Value);
112 uint8_t Value[sizeof(value_type)];
115 template<typename value_type>
116 class packed_endian_specific_integral<value_type, little, aligned> {
118 operator value_type() const {
119 return endian::read_le<value_type, aligned>(&Value);
125 template<typename value_type>
126 class packed_endian_specific_integral<value_type, big, aligned> {
128 operator value_type() const {
129 return endian::read_be<value_type, aligned>(&Value);
135 } // end namespace detail
137 typedef detail::packed_endian_specific_integral
138 <uint8_t, little, unaligned> ulittle8_t;
139 typedef detail::packed_endian_specific_integral
140 <uint16_t, little, unaligned> ulittle16_t;
141 typedef detail::packed_endian_specific_integral
142 <uint32_t, little, unaligned> ulittle32_t;
143 typedef detail::packed_endian_specific_integral
144 <uint64_t, little, unaligned> ulittle64_t;
146 typedef detail::packed_endian_specific_integral
147 <int8_t, little, unaligned> little8_t;
148 typedef detail::packed_endian_specific_integral
149 <int16_t, little, unaligned> little16_t;
150 typedef detail::packed_endian_specific_integral
151 <int32_t, little, unaligned> little32_t;
152 typedef detail::packed_endian_specific_integral
153 <int64_t, little, unaligned> little64_t;
155 typedef detail::packed_endian_specific_integral
156 <uint8_t, little, aligned> aligned_ulittle8_t;
157 typedef detail::packed_endian_specific_integral
158 <uint16_t, little, aligned> aligned_ulittle16_t;
159 typedef detail::packed_endian_specific_integral
160 <uint32_t, little, aligned> aligned_ulittle32_t;
161 typedef detail::packed_endian_specific_integral
162 <uint64_t, little, aligned> aligned_ulittle64_t;
164 typedef detail::packed_endian_specific_integral
165 <int8_t, little, aligned> aligned_little8_t;
166 typedef detail::packed_endian_specific_integral
167 <int16_t, little, aligned> aligned_little16_t;
168 typedef detail::packed_endian_specific_integral
169 <int32_t, little, aligned> aligned_little32_t;
170 typedef detail::packed_endian_specific_integral
171 <int64_t, little, aligned> aligned_little64_t;
173 typedef detail::packed_endian_specific_integral
174 <uint8_t, big, unaligned> ubig8_t;
175 typedef detail::packed_endian_specific_integral
176 <uint16_t, big, unaligned> ubig16_t;
177 typedef detail::packed_endian_specific_integral
178 <uint32_t, big, unaligned> ubig32_t;
179 typedef detail::packed_endian_specific_integral
180 <uint64_t, big, unaligned> ubig64_t;
182 typedef detail::packed_endian_specific_integral
183 <int8_t, big, unaligned> big8_t;
184 typedef detail::packed_endian_specific_integral
185 <int16_t, big, unaligned> big16_t;
186 typedef detail::packed_endian_specific_integral
187 <int32_t, big, unaligned> big32_t;
188 typedef detail::packed_endian_specific_integral
189 <int64_t, big, unaligned> big64_t;
191 typedef detail::packed_endian_specific_integral
192 <uint8_t, big, aligned> aligned_ubig8_t;
193 typedef detail::packed_endian_specific_integral
194 <uint16_t, big, aligned> aligned_ubig16_t;
195 typedef detail::packed_endian_specific_integral
196 <uint32_t, big, aligned> aligned_ubig32_t;
197 typedef detail::packed_endian_specific_integral
198 <uint64_t, big, aligned> aligned_ubig64_t;
200 typedef detail::packed_endian_specific_integral
201 <int8_t, big, aligned> aligned_big8_t;
202 typedef detail::packed_endian_specific_integral
203 <int16_t, big, aligned> aligned_big16_t;
204 typedef detail::packed_endian_specific_integral
205 <int32_t, big, aligned> aligned_big32_t;
206 typedef detail::packed_endian_specific_integral
207 <int64_t, big, aligned> aligned_big64_t;
209 } // end namespace llvm
210 } // end namespace support