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 21namespace llvm { 22namespace support { 23 24enum endianness {big, little}; 25enum alignment {unaligned, aligned}; 26 27namespace detail { 28 29template<typename value_type, alignment align> 30struct alignment_access_helper; 31 32template<typename value_type> 33struct 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) 41template<typename value_type> 42struct alignment_access_helper<value_type, unaligned> 43{ 44 value_type val; 45}; 46#pragma pack(pop) 47 48} // end namespace detail 49 50namespace 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 88namespace detail { 89 90template<typename value_type, 91 endianness endian, 92 alignment align> 93class packed_endian_specific_integral; 94 95template<typename value_type> 96class packed_endian_specific_integral<value_type, little, unaligned> { 97public: 98 operator value_type() const { 99 return endian::read_le<value_type, unaligned>(Value); 100 } 101private: 102 uint8_t Value[sizeof(value_type)]; 103}; 104 105template<typename value_type> 106class packed_endian_specific_integral<value_type, big, unaligned> { 107public: 108 operator value_type() const { 109 return endian::read_be<value_type, unaligned>(Value); 110 } 111private: 112 uint8_t Value[sizeof(value_type)]; 113}; 114 115template<typename value_type> 116class packed_endian_specific_integral<value_type, little, aligned> { 117public: 118 operator value_type() const { 119 return endian::read_le<value_type, aligned>(&Value); 120 } 121private: 122 value_type Value; 123}; 124 125template<typename value_type> 126class packed_endian_specific_integral<value_type, big, aligned> { 127public: 128 operator value_type() const { 129 return endian::read_be<value_type, aligned>(&Value); 130 } 131private: 132 value_type Value; 133}; 134 135} // end namespace detail 136 137typedef detail::packed_endian_specific_integral 138 <uint8_t, little, unaligned> ulittle8_t; 139typedef detail::packed_endian_specific_integral 140 <uint16_t, little, unaligned> ulittle16_t; 141typedef detail::packed_endian_specific_integral 142 <uint32_t, little, unaligned> ulittle32_t; 143typedef detail::packed_endian_specific_integral 144 <uint64_t, little, unaligned> ulittle64_t; 145 146typedef detail::packed_endian_specific_integral 147 <int8_t, little, unaligned> little8_t; 148typedef detail::packed_endian_specific_integral 149 <int16_t, little, unaligned> little16_t; 150typedef detail::packed_endian_specific_integral 151 <int32_t, little, unaligned> little32_t; 152typedef detail::packed_endian_specific_integral 153 <int64_t, little, unaligned> little64_t; 154 155typedef detail::packed_endian_specific_integral 156 <uint8_t, little, aligned> aligned_ulittle8_t; 157typedef detail::packed_endian_specific_integral 158 <uint16_t, little, aligned> aligned_ulittle16_t; 159typedef detail::packed_endian_specific_integral 160 <uint32_t, little, aligned> aligned_ulittle32_t; 161typedef detail::packed_endian_specific_integral 162 <uint64_t, little, aligned> aligned_ulittle64_t; 163 164typedef detail::packed_endian_specific_integral 165 <int8_t, little, aligned> aligned_little8_t; 166typedef detail::packed_endian_specific_integral 167 <int16_t, little, aligned> aligned_little16_t; 168typedef detail::packed_endian_specific_integral 169 <int32_t, little, aligned> aligned_little32_t; 170typedef detail::packed_endian_specific_integral 171 <int64_t, little, aligned> aligned_little64_t; 172 173typedef detail::packed_endian_specific_integral 174 <uint8_t, big, unaligned> ubig8_t; 175typedef detail::packed_endian_specific_integral 176 <uint16_t, big, unaligned> ubig16_t; 177typedef detail::packed_endian_specific_integral 178 <uint32_t, big, unaligned> ubig32_t; 179typedef detail::packed_endian_specific_integral 180 <uint64_t, big, unaligned> ubig64_t; 181 182typedef detail::packed_endian_specific_integral 183 <int8_t, big, unaligned> big8_t; 184typedef detail::packed_endian_specific_integral 185 <int16_t, big, unaligned> big16_t; 186typedef detail::packed_endian_specific_integral 187 <int32_t, big, unaligned> big32_t; 188typedef detail::packed_endian_specific_integral 189 <int64_t, big, unaligned> big64_t; 190 191typedef detail::packed_endian_specific_integral 192 <uint8_t, big, aligned> aligned_ubig8_t; 193typedef detail::packed_endian_specific_integral 194 <uint16_t, big, aligned> aligned_ubig16_t; 195typedef detail::packed_endian_specific_integral 196 <uint32_t, big, aligned> aligned_ubig32_t; 197typedef detail::packed_endian_specific_integral 198 <uint64_t, big, aligned> aligned_ubig64_t; 199 200typedef detail::packed_endian_specific_integral 201 <int8_t, big, aligned> aligned_big8_t; 202typedef detail::packed_endian_specific_integral 203 <int16_t, big, aligned> aligned_big16_t; 204typedef detail::packed_endian_specific_integral 205 <int32_t, big, aligned> aligned_big32_t; 206typedef 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 213