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 22 namespace llvm { 23 namespace support { 24 enum endianness {big, little, native}; 25 26 // These are named values for common alignments. 27 enum {aligned = 0, unaligned = 1}; 28 29 namespace 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 37 namespace endian { 38 template<typename value_type, endianness endian> 39 inline 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 45 template<typename value_type, 46 endianness endian, 47 std::size_t alignment> 48 inline 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 58 template<typename value_type, 59 endianness endian, 60 std::size_t alignment> 61 inline 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 70 namespace detail { 71 template<typename value_type, 72 endianness endian, 73 std::size_t alignment> 74 struct 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 85 private: 86 AlignedCharArray<PickAlignment<value_type, alignment>::value, 87 sizeof(value_type)> Value; 88 }; 89 } // end namespace detail 90 91 typedef detail::packed_endian_specific_integral 92 <uint8_t, little, unaligned> ulittle8_t; 93 typedef detail::packed_endian_specific_integral 94 <uint16_t, little, unaligned> ulittle16_t; 95 typedef detail::packed_endian_specific_integral 96 <uint32_t, little, unaligned> ulittle32_t; 97 typedef detail::packed_endian_specific_integral 98 <uint64_t, little, unaligned> ulittle64_t; 99 100 typedef detail::packed_endian_specific_integral 101 <int8_t, little, unaligned> little8_t; 102 typedef detail::packed_endian_specific_integral 103 <int16_t, little, unaligned> little16_t; 104 typedef detail::packed_endian_specific_integral 105 <int32_t, little, unaligned> little32_t; 106 typedef detail::packed_endian_specific_integral 107 <int64_t, little, unaligned> little64_t; 108 109 typedef detail::packed_endian_specific_integral 110 <uint8_t, little, aligned> aligned_ulittle8_t; 111 typedef detail::packed_endian_specific_integral 112 <uint16_t, little, aligned> aligned_ulittle16_t; 113 typedef detail::packed_endian_specific_integral 114 <uint32_t, little, aligned> aligned_ulittle32_t; 115 typedef detail::packed_endian_specific_integral 116 <uint64_t, little, aligned> aligned_ulittle64_t; 117 118 typedef detail::packed_endian_specific_integral 119 <int8_t, little, aligned> aligned_little8_t; 120 typedef detail::packed_endian_specific_integral 121 <int16_t, little, aligned> aligned_little16_t; 122 typedef detail::packed_endian_specific_integral 123 <int32_t, little, aligned> aligned_little32_t; 124 typedef detail::packed_endian_specific_integral 125 <int64_t, little, aligned> aligned_little64_t; 126 127 typedef detail::packed_endian_specific_integral 128 <uint8_t, big, unaligned> ubig8_t; 129 typedef detail::packed_endian_specific_integral 130 <uint16_t, big, unaligned> ubig16_t; 131 typedef detail::packed_endian_specific_integral 132 <uint32_t, big, unaligned> ubig32_t; 133 typedef detail::packed_endian_specific_integral 134 <uint64_t, big, unaligned> ubig64_t; 135 136 typedef detail::packed_endian_specific_integral 137 <int8_t, big, unaligned> big8_t; 138 typedef detail::packed_endian_specific_integral 139 <int16_t, big, unaligned> big16_t; 140 typedef detail::packed_endian_specific_integral 141 <int32_t, big, unaligned> big32_t; 142 typedef detail::packed_endian_specific_integral 143 <int64_t, big, unaligned> big64_t; 144 145 typedef detail::packed_endian_specific_integral 146 <uint8_t, big, aligned> aligned_ubig8_t; 147 typedef detail::packed_endian_specific_integral 148 <uint16_t, big, aligned> aligned_ubig16_t; 149 typedef detail::packed_endian_specific_integral 150 <uint32_t, big, aligned> aligned_ubig32_t; 151 typedef detail::packed_endian_specific_integral 152 <uint64_t, big, aligned> aligned_ubig64_t; 153 154 typedef detail::packed_endian_specific_integral 155 <int8_t, big, aligned> aligned_big8_t; 156 typedef detail::packed_endian_specific_integral 157 <int16_t, big, aligned> aligned_big16_t; 158 typedef detail::packed_endian_specific_integral 159 <int32_t, big, aligned> aligned_big32_t; 160 typedef detail::packed_endian_specific_integral 161 <int64_t, big, aligned> aligned_big64_t; 162 163 typedef detail::packed_endian_specific_integral 164 <uint16_t, native, unaligned> unaligned_uint16_t; 165 typedef detail::packed_endian_specific_integral 166 <uint32_t, native, unaligned> unaligned_uint32_t; 167 typedef detail::packed_endian_specific_integral 168 <uint64_t, native, unaligned> unaligned_uint64_t; 169 170 typedef detail::packed_endian_specific_integral 171 <int16_t, native, unaligned> unaligned_int16_t; 172 typedef detail::packed_endian_specific_integral 173 <int32_t, native, unaligned> unaligned_int32_t; 174 typedef 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