//===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file declares generic functions to read and write endian specific data. // //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_ENDIAN_H #define LLVM_SUPPORT_ENDIAN_H #include "llvm/Support/Host.h" #include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/type_traits.h" namespace llvm { namespace support { enum endianness {big, little}; enum alignment {unaligned, aligned}; namespace detail { template struct alignment_access_helper; template struct alignment_access_helper { value_type val; }; // Provides unaligned loads and stores. #pragma pack(push) #pragma pack(1) template struct alignment_access_helper { value_type val; }; #pragma pack(pop) } // end namespace detail namespace endian { template static value_type read_le(const void *memory) { value_type t = reinterpret_cast *>(memory)->val; if (sys::isBigEndianHost()) return sys::SwapByteOrder(t); return t; } template static void write_le(void *memory, value_type value) { if (sys::isBigEndianHost()) value = sys::SwapByteOrder(value); reinterpret_cast *> (memory)->val = value; } template static value_type read_be(const void *memory) { value_type t = reinterpret_cast *>(memory)->val; if (sys::isLittleEndianHost()) return sys::SwapByteOrder(t); return t; } template static void write_be(void *memory, value_type value) { if (sys::isLittleEndianHost()) value = sys::SwapByteOrder(value); reinterpret_cast *> (memory)->val = value; } } namespace detail { template class packed_endian_specific_integral; template class packed_endian_specific_integral { public: operator value_type() const { return endian::read_le(Value); } private: uint8_t Value[sizeof(value_type)]; }; template class packed_endian_specific_integral { public: operator value_type() const { return endian::read_be(Value); } private: uint8_t Value[sizeof(value_type)]; }; template class packed_endian_specific_integral { public: operator value_type() const { return endian::read_le(&Value); } private: value_type Value; }; template class packed_endian_specific_integral { public: operator value_type() const { return endian::read_be(&Value); } private: value_type Value; }; } // end namespace detail typedef detail::packed_endian_specific_integral ulittle8_t; typedef detail::packed_endian_specific_integral ulittle16_t; typedef detail::packed_endian_specific_integral ulittle32_t; typedef detail::packed_endian_specific_integral ulittle64_t; typedef detail::packed_endian_specific_integral little8_t; typedef detail::packed_endian_specific_integral little16_t; typedef detail::packed_endian_specific_integral little32_t; typedef detail::packed_endian_specific_integral little64_t; typedef detail::packed_endian_specific_integral aligned_ulittle8_t; typedef detail::packed_endian_specific_integral aligned_ulittle16_t; typedef detail::packed_endian_specific_integral aligned_ulittle32_t; typedef detail::packed_endian_specific_integral aligned_ulittle64_t; typedef detail::packed_endian_specific_integral aligned_little8_t; typedef detail::packed_endian_specific_integral aligned_little16_t; typedef detail::packed_endian_specific_integral aligned_little32_t; typedef detail::packed_endian_specific_integral aligned_little64_t; typedef detail::packed_endian_specific_integral ubig8_t; typedef detail::packed_endian_specific_integral ubig16_t; typedef detail::packed_endian_specific_integral ubig32_t; typedef detail::packed_endian_specific_integral ubig64_t; typedef detail::packed_endian_specific_integral big8_t; typedef detail::packed_endian_specific_integral big16_t; typedef detail::packed_endian_specific_integral big32_t; typedef detail::packed_endian_specific_integral big64_t; typedef detail::packed_endian_specific_integral aligned_ubig8_t; typedef detail::packed_endian_specific_integral aligned_ubig16_t; typedef detail::packed_endian_specific_integral aligned_ubig32_t; typedef detail::packed_endian_specific_integral aligned_ubig64_t; typedef detail::packed_endian_specific_integral aligned_big8_t; typedef detail::packed_endian_specific_integral aligned_big16_t; typedef detail::packed_endian_specific_integral aligned_big32_t; typedef detail::packed_endian_specific_integral aligned_big64_t; } // end namespace llvm } // end namespace support #endif