]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/include/llvm/Support/Endian.h
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.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   static 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   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;
67   }
68
69   template<typename value_type, alignment align>
70   static 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   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;
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 private:
102   uint8_t Value[sizeof(value_type)];
103 };
104
105 template<typename value_type>
106 class packed_endian_specific_integral<value_type, big, unaligned> {
107 public:
108   operator value_type() const {
109     return endian::read_be<value_type, unaligned>(Value);
110   }
111 private:
112   uint8_t Value[sizeof(value_type)];
113 };
114
115 template<typename value_type>
116 class packed_endian_specific_integral<value_type, little, aligned> {
117 public:
118   operator value_type() const {
119     return endian::read_le<value_type, aligned>(&Value);
120   }
121 private:
122   value_type Value;
123 };
124
125 template<typename value_type>
126 class packed_endian_specific_integral<value_type, big, aligned> {
127 public:
128   operator value_type() const {
129     return endian::read_be<value_type, aligned>(&Value);
130   }
131 private:
132   value_type Value;
133 };
134
135 } // end namespace detail
136
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;
145
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;
154
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;
163
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;
172
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;
181
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;
190
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;
199
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;
208
209 } // end namespace llvm
210 } // end namespace support
211
212 #endif