Endian.h revision 218885
1221828Sgrehan//===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===// 2221828Sgrehan// 3221828Sgrehan// The LLVM Compiler Infrastructure 4221828Sgrehan// 5221828Sgrehan// This file is distributed under the University of Illinois Open Source 6221828Sgrehan// License. See LICENSE.TXT for details. 7221828Sgrehan// 8221828Sgrehan//===----------------------------------------------------------------------===// 9221828Sgrehan// 10221828Sgrehan// This file declares generic functions to read and write endian specific data. 11221828Sgrehan// 12221828Sgrehan//===----------------------------------------------------------------------===// 13221828Sgrehan 14221828Sgrehan#ifndef LLVM_SUPPORT_ENDIAN_H 15221828Sgrehan#define LLVM_SUPPORT_ENDIAN_H 16221828Sgrehan 17221828Sgrehan#include "llvm/Config/config.h" 18221828Sgrehan#include "llvm/Support/Host.h" 19221828Sgrehan#include "llvm/Support/SwapByteOrder.h" 20221828Sgrehan#include "llvm/Support/type_traits.h" 21221828Sgrehan 22221828Sgrehannamespace llvm { 23221828Sgrehannamespace support { 24221828Sgrehan 25221828Sgrehanenum endianness {big, little}; 26221828Sgrehanenum alignment {unaligned, aligned}; 27221828Sgrehan 28221828Sgrehannamespace detail { 29221828Sgrehan 30221828Sgrehantemplate<typename value_type, alignment align> 31221828Sgrehanstruct alignment_access_helper; 32221828Sgrehan 33221828Sgrehantemplate<typename value_type> 34256072Sneelstruct alignment_access_helper<value_type, aligned> 35256072Sneel{ 36221828Sgrehan value_type val; 37221828Sgrehan}; 38221828Sgrehan 39222112Sneel// Provides unaligned loads and stores. 40222112Sneel#pragma pack(push) 41222112Sneel#pragma pack(1) 42221828Sgrehantemplate<typename value_type> 43221828Sgrehanstruct alignment_access_helper<value_type, unaligned> 44221828Sgrehan{ 45221828Sgrehan value_type val; 46221828Sgrehan}; 47221828Sgrehan#pragma pack(pop) 48221828Sgrehan 49221828Sgrehan} // end namespace detail 50221828Sgrehan 51221828Sgrehannamespace endian { 52221828Sgrehan template<typename value_type, alignment align> 53221828Sgrehan static value_type read_le(const void *memory) { 54221828Sgrehan value_type t = 55221828Sgrehan reinterpret_cast<const detail::alignment_access_helper 56221828Sgrehan <value_type, align> *>(memory)->val; 57221828Sgrehan if (sys::isBigEndianHost()) 58221828Sgrehan return sys::SwapByteOrder(t); 59221828Sgrehan return t; 60221828Sgrehan } 61221828Sgrehan 62221828Sgrehan template<typename value_type, alignment align> 63221828Sgrehan static void write_le(void *memory, value_type value) { 64221828Sgrehan if (sys::isBigEndianHost()) 65221828Sgrehan value = sys::SwapByteOrder(value); 66221828Sgrehan reinterpret_cast<detail::alignment_access_helper<value_type, align> *> 67221828Sgrehan (memory)->val = value; 68221828Sgrehan } 69221828Sgrehan 70221828Sgrehan template<typename value_type, alignment align> 71222112Sneel static value_type read_be(const void *memory) { 72221828Sgrehan value_type t = 73256072Sneel reinterpret_cast<const detail::alignment_access_helper 74256072Sneel <value_type, align> *>(memory)->val; 75256072Sneel if (sys::isLittleEndianHost()) 76256072Sneel return sys::SwapByteOrder(t); 77256072Sneel return t; 78256072Sneel } 79256072Sneel 80256072Sneel template<typename value_type, alignment align> 81256072Sneel static void write_be(void *memory, value_type value) { 82221828Sgrehan if (sys::isLittleEndianHost()) 83221828Sgrehan value = sys::SwapByteOrder(value); 84221828Sgrehan reinterpret_cast<detail::alignment_access_helper<value_type, align> *> 85221828Sgrehan (memory)->val = value; 86221828Sgrehan } 87256645Sneel} 88221828Sgrehan 89221828Sgrehannamespace detail { 90221828Sgrehan 91221828Sgrehantemplate<typename value_type, 92221828Sgrehan endianness endian, 93221828Sgrehan alignment align> 94221828Sgrehanclass packed_endian_specific_integral; 95221828Sgrehan 96221828Sgrehantemplate<typename value_type> 97221828Sgrehanclass packed_endian_specific_integral<value_type, little, unaligned> { 98221828Sgrehanpublic: 99221828Sgrehan operator value_type() const { 100221828Sgrehan return endian::read_le<value_type, unaligned>(Value); 101221828Sgrehan } 102221828Sgrehanprivate: 103256072Sneel uint8_t Value[sizeof(value_type)]; 104221828Sgrehan}; 105221828Sgrehan 106221828Sgrehantemplate<typename value_type> 107221828Sgrehanclass packed_endian_specific_integral<value_type, big, unaligned> { 108221828Sgrehanpublic: 109221828Sgrehan operator value_type() const { 110221828Sgrehan return endian::read_be<value_type, unaligned>(Value); 111221828Sgrehan } 112221828Sgrehanprivate: 113221828Sgrehan uint8_t Value[sizeof(value_type)]; 114241921Sneel}; 115256072Sneel 116221828Sgrehantemplate<typename value_type> 117221828Sgrehanclass packed_endian_specific_integral<value_type, little, aligned> { 118221828Sgrehanpublic: 119221828Sgrehan operator value_type() const { 120221828Sgrehan return endian::read_le<value_type, aligned>(&Value); 121221828Sgrehan } 122241921Sneelprivate: 123256072Sneel value_type Value; 124221828Sgrehan}; 125221828Sgrehan 126221828Sgrehantemplate<typename value_type> 127221828Sgrehanclass packed_endian_specific_integral<value_type, big, aligned> { 128221828Sgrehanpublic: 129221828Sgrehan operator value_type() const { 130221828Sgrehan return endian::read_be<value_type, aligned>(&Value); 131221828Sgrehan } 132221828Sgrehanprivate: 133221828Sgrehan value_type Value; 134}; 135 136} // end namespace detail 137 138typedef detail::packed_endian_specific_integral 139 <uint8_t, little, unaligned> ulittle8_t; 140typedef detail::packed_endian_specific_integral 141 <uint16_t, little, unaligned> ulittle16_t; 142typedef detail::packed_endian_specific_integral 143 <uint32_t, little, unaligned> ulittle32_t; 144typedef detail::packed_endian_specific_integral 145 <uint64_t, little, unaligned> ulittle64_t; 146 147typedef detail::packed_endian_specific_integral 148 <int8_t, little, unaligned> little8_t; 149typedef detail::packed_endian_specific_integral 150 <int16_t, little, unaligned> little16_t; 151typedef detail::packed_endian_specific_integral 152 <int32_t, little, unaligned> little32_t; 153typedef detail::packed_endian_specific_integral 154 <int64_t, little, unaligned> little64_t; 155 156typedef detail::packed_endian_specific_integral 157 <uint8_t, little, aligned> aligned_ulittle8_t; 158typedef detail::packed_endian_specific_integral 159 <uint16_t, little, aligned> aligned_ulittle16_t; 160typedef detail::packed_endian_specific_integral 161 <uint32_t, little, aligned> aligned_ulittle32_t; 162typedef detail::packed_endian_specific_integral 163 <uint64_t, little, aligned> aligned_ulittle64_t; 164 165typedef detail::packed_endian_specific_integral 166 <int8_t, little, aligned> aligned_little8_t; 167typedef detail::packed_endian_specific_integral 168 <int16_t, little, aligned> aligned_little16_t; 169typedef detail::packed_endian_specific_integral 170 <int32_t, little, aligned> aligned_little32_t; 171typedef detail::packed_endian_specific_integral 172 <int64_t, little, aligned> aligned_little64_t; 173 174typedef detail::packed_endian_specific_integral 175 <uint8_t, big, unaligned> ubig8_t; 176typedef detail::packed_endian_specific_integral 177 <uint16_t, big, unaligned> ubig16_t; 178typedef detail::packed_endian_specific_integral 179 <uint32_t, big, unaligned> ubig32_t; 180typedef detail::packed_endian_specific_integral 181 <uint64_t, big, unaligned> ubig64_t; 182 183typedef detail::packed_endian_specific_integral 184 <int8_t, big, unaligned> big8_t; 185typedef detail::packed_endian_specific_integral 186 <int16_t, big, unaligned> big16_t; 187typedef detail::packed_endian_specific_integral 188 <int32_t, big, unaligned> big32_t; 189typedef detail::packed_endian_specific_integral 190 <int64_t, big, unaligned> big64_t; 191 192typedef detail::packed_endian_specific_integral 193 <uint8_t, big, aligned> aligned_ubig8_t; 194typedef detail::packed_endian_specific_integral 195 <uint16_t, big, aligned> aligned_ubig16_t; 196typedef detail::packed_endian_specific_integral 197 <uint32_t, big, aligned> aligned_ubig32_t; 198typedef detail::packed_endian_specific_integral 199 <uint64_t, big, aligned> aligned_ubig64_t; 200 201typedef detail::packed_endian_specific_integral 202 <int8_t, big, aligned> aligned_big8_t; 203typedef detail::packed_endian_specific_integral 204 <int16_t, big, aligned> aligned_big16_t; 205typedef detail::packed_endian_specific_integral 206 <int32_t, big, aligned> aligned_big32_t; 207typedef detail::packed_endian_specific_integral 208 <int64_t, big, aligned> aligned_big64_t; 209 210} // end namespace llvm 211} // end namespace support 212 213#endif 214