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/Support/Host.h"
19 #include "llvm/Support/SwapByteOrder.h"
20 #include "llvm/Support/type_traits.h"
25 enum endianness {big, little};
26 enum alignment {unaligned, aligned};
30 template<typename value_type, alignment align>
31 struct alignment_access_helper;
33 template<typename value_type>
34 struct alignment_access_helper<value_type, aligned>
39 // Provides unaligned loads and stores.
42 template<typename value_type>
43 struct alignment_access_helper<value_type, unaligned>
49 } // end namespace detail
52 template<typename value_type, alignment align>
53 static value_type read_le(const void *memory) {
55 reinterpret_cast<const detail::alignment_access_helper
56 <value_type, align> *>(memory)->val;
57 if (sys::isBigEndianHost())
58 return sys::SwapByteOrder(t);
62 template<typename value_type, alignment align>
63 static void write_le(void *memory, value_type value) {
64 if (sys::isBigEndianHost())
65 value = sys::SwapByteOrder(value);
66 reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
67 (memory)->val = value;
70 template<typename value_type, alignment align>
71 static value_type read_be(const void *memory) {
73 reinterpret_cast<const detail::alignment_access_helper
74 <value_type, align> *>(memory)->val;
75 if (sys::isLittleEndianHost())
76 return sys::SwapByteOrder(t);
80 template<typename value_type, alignment align>
81 static void write_be(void *memory, value_type value) {
82 if (sys::isLittleEndianHost())
83 value = sys::SwapByteOrder(value);
84 reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
85 (memory)->val = value;
91 template<typename value_type,
94 class packed_endian_specific_integral;
96 template<typename value_type>
97 class packed_endian_specific_integral<value_type, little, unaligned> {
99 operator value_type() const {
100 return endian::read_le<value_type, unaligned>(Value);
103 uint8_t Value[sizeof(value_type)];
106 template<typename value_type>
107 class packed_endian_specific_integral<value_type, big, unaligned> {
109 operator value_type() const {
110 return endian::read_be<value_type, unaligned>(Value);
113 uint8_t Value[sizeof(value_type)];
116 template<typename value_type>
117 class packed_endian_specific_integral<value_type, little, aligned> {
119 operator value_type() const {
120 return endian::read_le<value_type, aligned>(&Value);
126 template<typename value_type>
127 class packed_endian_specific_integral<value_type, big, aligned> {
129 operator value_type() const {
130 return endian::read_be<value_type, aligned>(&Value);
136 } // end namespace detail
138 typedef detail::packed_endian_specific_integral
139 <uint8_t, little, unaligned> ulittle8_t;
140 typedef detail::packed_endian_specific_integral
141 <uint16_t, little, unaligned> ulittle16_t;
142 typedef detail::packed_endian_specific_integral
143 <uint32_t, little, unaligned> ulittle32_t;
144 typedef detail::packed_endian_specific_integral
145 <uint64_t, little, unaligned> ulittle64_t;
147 typedef detail::packed_endian_specific_integral
148 <int8_t, little, unaligned> little8_t;
149 typedef detail::packed_endian_specific_integral
150 <int16_t, little, unaligned> little16_t;
151 typedef detail::packed_endian_specific_integral
152 <int32_t, little, unaligned> little32_t;
153 typedef detail::packed_endian_specific_integral
154 <int64_t, little, unaligned> little64_t;
156 typedef detail::packed_endian_specific_integral
157 <uint8_t, little, aligned> aligned_ulittle8_t;
158 typedef detail::packed_endian_specific_integral
159 <uint16_t, little, aligned> aligned_ulittle16_t;
160 typedef detail::packed_endian_specific_integral
161 <uint32_t, little, aligned> aligned_ulittle32_t;
162 typedef detail::packed_endian_specific_integral
163 <uint64_t, little, aligned> aligned_ulittle64_t;
165 typedef detail::packed_endian_specific_integral
166 <int8_t, little, aligned> aligned_little8_t;
167 typedef detail::packed_endian_specific_integral
168 <int16_t, little, aligned> aligned_little16_t;
169 typedef detail::packed_endian_specific_integral
170 <int32_t, little, aligned> aligned_little32_t;
171 typedef detail::packed_endian_specific_integral
172 <int64_t, little, aligned> aligned_little64_t;
174 typedef detail::packed_endian_specific_integral
175 <uint8_t, big, unaligned> ubig8_t;
176 typedef detail::packed_endian_specific_integral
177 <uint16_t, big, unaligned> ubig16_t;
178 typedef detail::packed_endian_specific_integral
179 <uint32_t, big, unaligned> ubig32_t;
180 typedef detail::packed_endian_specific_integral
181 <uint64_t, big, unaligned> ubig64_t;
183 typedef detail::packed_endian_specific_integral
184 <int8_t, big, unaligned> big8_t;
185 typedef detail::packed_endian_specific_integral
186 <int16_t, big, unaligned> big16_t;
187 typedef detail::packed_endian_specific_integral
188 <int32_t, big, unaligned> big32_t;
189 typedef detail::packed_endian_specific_integral
190 <int64_t, big, unaligned> big64_t;
192 typedef detail::packed_endian_specific_integral
193 <uint8_t, big, aligned> aligned_ubig8_t;
194 typedef detail::packed_endian_specific_integral
195 <uint16_t, big, aligned> aligned_ubig16_t;
196 typedef detail::packed_endian_specific_integral
197 <uint32_t, big, aligned> aligned_ubig32_t;
198 typedef detail::packed_endian_specific_integral
199 <uint64_t, big, aligned> aligned_ubig64_t;
201 typedef detail::packed_endian_specific_integral
202 <int8_t, big, aligned> aligned_big8_t;
203 typedef detail::packed_endian_specific_integral
204 <int16_t, big, aligned> aligned_big16_t;
205 typedef detail::packed_endian_specific_integral
206 <int32_t, big, aligned> aligned_big32_t;
207 typedef detail::packed_endian_specific_integral
208 <int64_t, big, aligned> aligned_big64_t;
210 } // end namespace llvm
211 } // end namespace support