LLVM API Documentation

Endian.h
Go to the documentation of this file.
00001 //===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file declares generic functions to read and write endian specific data.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_SUPPORT_ENDIAN_H
00015 #define LLVM_SUPPORT_ENDIAN_H
00016 
00017 #include "llvm/Support/AlignOf.h"
00018 #include "llvm/Support/Host.h"
00019 #include "llvm/Support/SwapByteOrder.h"
00020 #include "llvm/Support/type_traits.h"
00021 
00022 namespace llvm {
00023 namespace support {
00024 enum endianness {big, little, native};
00025 
00026 // These are named values for common alignments.
00027 enum {aligned = 0, unaligned = 1};
00028 
00029 namespace detail {
00030   /// \brief ::value is either alignment, or alignof(T) if alignment is 0.
00031   template<class T, int alignment>
00032   struct PickAlignment {
00033     enum {value = alignment == 0 ? AlignOf<T>::Alignment : alignment};
00034   };
00035 } // end namespace detail
00036 
00037 namespace endian {
00038 template<typename value_type, endianness endian>
00039 inline value_type byte_swap(value_type value) {
00040   if (endian != native && sys::IsBigEndianHost != (endian == big))
00041     return sys::SwapByteOrder(value);
00042   return value;
00043 }
00044 
00045 template<typename value_type,
00046          endianness endian,
00047          std::size_t alignment>
00048 inline value_type read(const void *memory) {
00049   value_type ret;
00050 
00051   memcpy(&ret,
00052          LLVM_ASSUME_ALIGNED(memory,
00053            (detail::PickAlignment<value_type, alignment>::value)),
00054          sizeof(value_type));
00055   return byte_swap<value_type, endian>(ret);
00056 }
00057 
00058 template<typename value_type,
00059          endianness endian,
00060          std::size_t alignment>
00061 inline void write(void *memory, value_type value) {
00062   value = byte_swap<value_type, endian>(value);
00063   memcpy(LLVM_ASSUME_ALIGNED(memory,
00064            (detail::PickAlignment<value_type, alignment>::value)),
00065          &value,
00066          sizeof(value_type));
00067 }
00068 } // end namespace endian
00069 
00070 namespace detail {
00071 template<typename value_type,
00072          endianness endian,
00073          std::size_t alignment>
00074 struct packed_endian_specific_integral {
00075   operator value_type() const {
00076     return endian::read<value_type, endian, alignment>(
00077       (const void*)Value.buffer);
00078   }
00079 
00080   void operator=(value_type newValue) {
00081     endian::write<value_type, endian, alignment>(
00082       (void*)Value.buffer, newValue);
00083   }
00084 
00085 private:
00086   AlignedCharArray<PickAlignment<value_type, alignment>::value,
00087                    sizeof(value_type)> Value;
00088 };
00089 } // end namespace detail
00090 
00091 typedef detail::packed_endian_specific_integral
00092                   <uint8_t, little, unaligned>  ulittle8_t;
00093 typedef detail::packed_endian_specific_integral
00094                   <uint16_t, little, unaligned> ulittle16_t;
00095 typedef detail::packed_endian_specific_integral
00096                   <uint32_t, little, unaligned> ulittle32_t;
00097 typedef detail::packed_endian_specific_integral
00098                   <uint64_t, little, unaligned> ulittle64_t;
00099 
00100 typedef detail::packed_endian_specific_integral
00101                    <int8_t, little, unaligned>  little8_t;
00102 typedef detail::packed_endian_specific_integral
00103                    <int16_t, little, unaligned> little16_t;
00104 typedef detail::packed_endian_specific_integral
00105                    <int32_t, little, unaligned> little32_t;
00106 typedef detail::packed_endian_specific_integral
00107                    <int64_t, little, unaligned> little64_t;
00108 
00109 typedef detail::packed_endian_specific_integral
00110                     <uint8_t, little, aligned>  aligned_ulittle8_t;
00111 typedef detail::packed_endian_specific_integral
00112                     <uint16_t, little, aligned> aligned_ulittle16_t;
00113 typedef detail::packed_endian_specific_integral
00114                     <uint32_t, little, aligned> aligned_ulittle32_t;
00115 typedef detail::packed_endian_specific_integral
00116                     <uint64_t, little, aligned> aligned_ulittle64_t;
00117 
00118 typedef detail::packed_endian_specific_integral
00119                      <int8_t, little, aligned>  aligned_little8_t;
00120 typedef detail::packed_endian_specific_integral
00121                      <int16_t, little, aligned> aligned_little16_t;
00122 typedef detail::packed_endian_specific_integral
00123                      <int32_t, little, aligned> aligned_little32_t;
00124 typedef detail::packed_endian_specific_integral
00125                      <int64_t, little, aligned> aligned_little64_t;
00126 
00127 typedef detail::packed_endian_specific_integral
00128                   <uint8_t, big, unaligned>     ubig8_t;
00129 typedef detail::packed_endian_specific_integral
00130                   <uint16_t, big, unaligned>    ubig16_t;
00131 typedef detail::packed_endian_specific_integral
00132                   <uint32_t, big, unaligned>    ubig32_t;
00133 typedef detail::packed_endian_specific_integral
00134                   <uint64_t, big, unaligned>    ubig64_t;
00135 
00136 typedef detail::packed_endian_specific_integral
00137                    <int8_t, big, unaligned>     big8_t;
00138 typedef detail::packed_endian_specific_integral
00139                    <int16_t, big, unaligned>    big16_t;
00140 typedef detail::packed_endian_specific_integral
00141                    <int32_t, big, unaligned>    big32_t;
00142 typedef detail::packed_endian_specific_integral
00143                    <int64_t, big, unaligned>    big64_t;
00144 
00145 typedef detail::packed_endian_specific_integral
00146                     <uint8_t, big, aligned>     aligned_ubig8_t;
00147 typedef detail::packed_endian_specific_integral
00148                     <uint16_t, big, aligned>    aligned_ubig16_t;
00149 typedef detail::packed_endian_specific_integral
00150                     <uint32_t, big, aligned>    aligned_ubig32_t;
00151 typedef detail::packed_endian_specific_integral
00152                     <uint64_t, big, aligned>    aligned_ubig64_t;
00153 
00154 typedef detail::packed_endian_specific_integral
00155                      <int8_t, big, aligned>     aligned_big8_t;
00156 typedef detail::packed_endian_specific_integral
00157                      <int16_t, big, aligned>    aligned_big16_t;
00158 typedef detail::packed_endian_specific_integral
00159                      <int32_t, big, aligned>    aligned_big32_t;
00160 typedef detail::packed_endian_specific_integral
00161                      <int64_t, big, aligned>    aligned_big64_t;
00162 
00163 typedef detail::packed_endian_specific_integral
00164                   <uint16_t, native, unaligned> unaligned_uint16_t;
00165 typedef detail::packed_endian_specific_integral
00166                   <uint32_t, native, unaligned> unaligned_uint32_t;
00167 typedef detail::packed_endian_specific_integral
00168                   <uint64_t, native, unaligned> unaligned_uint64_t;
00169 
00170 typedef detail::packed_endian_specific_integral
00171                    <int16_t, native, unaligned> unaligned_int16_t;
00172 typedef detail::packed_endian_specific_integral
00173                    <int32_t, native, unaligned> unaligned_int32_t;
00174 typedef detail::packed_endian_specific_integral
00175                    <int64_t, native, unaligned> unaligned_int64_t;
00176 } // end namespace llvm
00177 } // end namespace support
00178 
00179 #endif