Endian.h revision 21a01d1ea89dba97c4f9e1f9f41485729a4046bc
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/AlignOf.h" 18#include "llvm/Support/Host.h" 19#include "llvm/Support/SwapByteOrder.h" 20#include "llvm/Support/type_traits.h" 21 22namespace llvm { 23namespace support { 24enum endianness {big, little, native}; 25 26// These are named values for common alignments. 27enum {aligned = 0, unaligned = 1}; 28 29namespace detail { 30 /// \brief ::value is either alignment, or alignof(T) if alignment is 0. 31 template<class T, int alignment> 32 struct PickAlignment { 33 enum {value = alignment == 0 ? AlignOf<T>::Alignment : alignment}; 34 }; 35} // end namespace detail 36 37namespace endian { 38template<typename value_type, endianness endian> 39inline value_type byte_swap(value_type value) { 40 if (endian != native && sys::IsBigEndianHost != (endian == big)) 41 return sys::SwapByteOrder(value); 42 return value; 43} 44 45template<typename value_type, 46 endianness endian, 47 std::size_t alignment> 48inline value_type read(const void *memory) { 49 value_type ret; 50 51 memcpy(&ret, 52 LLVM_ASSUME_ALIGNED(memory, 53 (detail::PickAlignment<value_type, alignment>::value)), 54 sizeof(value_type)); 55 return byte_swap<value_type, endian>(ret); 56} 57 58template<typename value_type, 59 endianness endian, 60 std::size_t alignment> 61inline void write(void *memory, value_type value) { 62 value = byte_swap<value_type, endian>(value); 63 memcpy(LLVM_ASSUME_ALIGNED(memory, 64 (detail::PickAlignment<value_type, alignment>::value)), 65 &value, 66 sizeof(value_type)); 67} 68} // end namespace endian 69 70namespace detail { 71template<typename value_type, 72 endianness endian, 73 std::size_t alignment> 74struct packed_endian_specific_integral { 75 operator value_type() const { 76 return endian::read<value_type, endian, alignment>( 77 (const void*)Value.buffer); 78 } 79 80 void operator=(value_type newValue) { 81 endian::write<value_type, endian, alignment>( 82 (void*)Value.buffer, newValue); 83 } 84 85private: 86 AlignedCharArray<PickAlignment<value_type, alignment>::value, 87 sizeof(value_type)> Value; 88}; 89} // end namespace detail 90 91typedef detail::packed_endian_specific_integral 92 <uint8_t, little, unaligned> ulittle8_t; 93typedef detail::packed_endian_specific_integral 94 <uint16_t, little, unaligned> ulittle16_t; 95typedef detail::packed_endian_specific_integral 96 <uint32_t, little, unaligned> ulittle32_t; 97typedef detail::packed_endian_specific_integral 98 <uint64_t, little, unaligned> ulittle64_t; 99 100typedef detail::packed_endian_specific_integral 101 <int8_t, little, unaligned> little8_t; 102typedef detail::packed_endian_specific_integral 103 <int16_t, little, unaligned> little16_t; 104typedef detail::packed_endian_specific_integral 105 <int32_t, little, unaligned> little32_t; 106typedef detail::packed_endian_specific_integral 107 <int64_t, little, unaligned> little64_t; 108 109typedef detail::packed_endian_specific_integral 110 <uint8_t, little, aligned> aligned_ulittle8_t; 111typedef detail::packed_endian_specific_integral 112 <uint16_t, little, aligned> aligned_ulittle16_t; 113typedef detail::packed_endian_specific_integral 114 <uint32_t, little, aligned> aligned_ulittle32_t; 115typedef detail::packed_endian_specific_integral 116 <uint64_t, little, aligned> aligned_ulittle64_t; 117 118typedef detail::packed_endian_specific_integral 119 <int8_t, little, aligned> aligned_little8_t; 120typedef detail::packed_endian_specific_integral 121 <int16_t, little, aligned> aligned_little16_t; 122typedef detail::packed_endian_specific_integral 123 <int32_t, little, aligned> aligned_little32_t; 124typedef detail::packed_endian_specific_integral 125 <int64_t, little, aligned> aligned_little64_t; 126 127typedef detail::packed_endian_specific_integral 128 <uint8_t, big, unaligned> ubig8_t; 129typedef detail::packed_endian_specific_integral 130 <uint16_t, big, unaligned> ubig16_t; 131typedef detail::packed_endian_specific_integral 132 <uint32_t, big, unaligned> ubig32_t; 133typedef detail::packed_endian_specific_integral 134 <uint64_t, big, unaligned> ubig64_t; 135 136typedef detail::packed_endian_specific_integral 137 <int8_t, big, unaligned> big8_t; 138typedef detail::packed_endian_specific_integral 139 <int16_t, big, unaligned> big16_t; 140typedef detail::packed_endian_specific_integral 141 <int32_t, big, unaligned> big32_t; 142typedef detail::packed_endian_specific_integral 143 <int64_t, big, unaligned> big64_t; 144 145typedef detail::packed_endian_specific_integral 146 <uint8_t, big, aligned> aligned_ubig8_t; 147typedef detail::packed_endian_specific_integral 148 <uint16_t, big, aligned> aligned_ubig16_t; 149typedef detail::packed_endian_specific_integral 150 <uint32_t, big, aligned> aligned_ubig32_t; 151typedef detail::packed_endian_specific_integral 152 <uint64_t, big, aligned> aligned_ubig64_t; 153 154typedef detail::packed_endian_specific_integral 155 <int8_t, big, aligned> aligned_big8_t; 156typedef detail::packed_endian_specific_integral 157 <int16_t, big, aligned> aligned_big16_t; 158typedef detail::packed_endian_specific_integral 159 <int32_t, big, aligned> aligned_big32_t; 160typedef detail::packed_endian_specific_integral 161 <int64_t, big, aligned> aligned_big64_t; 162 163typedef detail::packed_endian_specific_integral 164 <uint16_t, native, unaligned> unaligned_uint16_t; 165typedef detail::packed_endian_specific_integral 166 <uint32_t, native, unaligned> unaligned_uint32_t; 167typedef detail::packed_endian_specific_integral 168 <uint64_t, native, unaligned> unaligned_uint64_t; 169 170typedef detail::packed_endian_specific_integral 171 <int16_t, native, unaligned> unaligned_int16_t; 172typedef detail::packed_endian_specific_integral 173 <int32_t, native, unaligned> unaligned_int32_t; 174typedef detail::packed_endian_specific_integral 175 <int64_t, native, unaligned> unaligned_int64_t; 176} // end namespace llvm 177} // end namespace support 178 179#endif 180