]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/include/llvm/Support/Endian.h
MFC r244628:
[FreeBSD/stable/9.git] / contrib / llvm / include / llvm / Support / Endian.h
1 //===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares generic functions to read and write endian specific data.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_SUPPORT_ENDIAN_H
15 #define LLVM_SUPPORT_ENDIAN_H
16
17 #include "llvm/Support/Host.h"
18 #include "llvm/Support/SwapByteOrder.h"
19 #include "llvm/Support/type_traits.h"
20
21 namespace llvm {
22 namespace support {
23
24 enum endianness {big, little};
25 enum alignment {unaligned, aligned};
26
27 namespace detail {
28
29 template<typename value_type, alignment align>
30 struct alignment_access_helper;
31
32 template<typename value_type>
33 struct alignment_access_helper<value_type, aligned>
34 {
35   value_type val;
36 };
37
38 // Provides unaligned loads and stores.
39 #pragma pack(push)
40 #pragma pack(1)
41 template<typename value_type>
42 struct alignment_access_helper<value_type, unaligned>
43 {
44   value_type val;
45 };
46 #pragma pack(pop)
47
48 } // end namespace detail
49
50 namespace endian {
51   template<typename value_type, alignment align>
52   inline value_type read_le(const void *memory) {
53     value_type t =
54       reinterpret_cast<const detail::alignment_access_helper
55         <value_type, align> *>(memory)->val;
56     if (sys::isBigEndianHost())
57       return sys::SwapByteOrder(t);
58     return t;
59   }
60
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;
67   }
68
69   template<typename value_type, alignment align>
70   inline value_type read_be(const void *memory) {
71     value_type t =
72       reinterpret_cast<const detail::alignment_access_helper
73         <value_type, align> *>(memory)->val;
74     if (sys::isLittleEndianHost())
75       return sys::SwapByteOrder(t);
76     return t;
77   }
78
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;
85   }
86 }
87
88 namespace detail {
89
90 template<typename value_type,
91          endianness endian,
92          alignment  align>
93 class packed_endian_specific_integral;
94
95 template<typename value_type>
96 class packed_endian_specific_integral<value_type, little, unaligned> {
97 public:
98   operator value_type() const {
99     return endian::read_le<value_type, unaligned>(Value);
100   }
101   void operator=(value_type newValue) {
102     endian::write_le<value_type, unaligned>((void *)&Value, newValue);
103   }
104 private:
105   uint8_t Value[sizeof(value_type)];
106 };
107
108 template<typename value_type>
109 class packed_endian_specific_integral<value_type, big, unaligned> {
110 public:
111   operator value_type() const {
112     return endian::read_be<value_type, unaligned>(Value);
113   }
114   void operator=(value_type newValue) {
115     endian::write_be<value_type, unaligned>((void *)&Value, newValue);
116   }
117 private:
118   uint8_t Value[sizeof(value_type)];
119 };
120
121 template<typename value_type>
122 class packed_endian_specific_integral<value_type, little, aligned> {
123 public:
124   operator value_type() const {
125     return endian::read_le<value_type, aligned>(&Value);
126   }
127   void operator=(value_type newValue) {
128     endian::write_le<value_type, aligned>((void *)&Value, newValue);
129   }
130 private:
131   value_type Value;
132 };
133
134 template<typename value_type>
135 class packed_endian_specific_integral<value_type, big, aligned> {
136 public:
137   operator value_type() const {
138     return endian::read_be<value_type, aligned>(&Value);
139   }
140   void operator=(value_type newValue) {
141     endian::write_be<value_type, aligned>((void *)&Value, newValue);
142   }
143 private:
144   value_type Value;
145 };
146
147 } // end namespace detail
148
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;
157
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;
166
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;
175
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;
184
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;
193
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;
202
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;
211
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;
220
221 } // end namespace llvm
222 } // end namespace support
223
224 #endif