LLVM API Documentation

SwapByteOrder.h
Go to the documentation of this file.
00001 //===- SwapByteOrder.h - Generic and optimized byte swaps -------*- 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 and optimized functions to swap the byte order of
00011 // an integral type.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_SUPPORT_SWAPBYTEORDER_H
00016 #define LLVM_SUPPORT_SWAPBYTEORDER_H
00017 
00018 #include "llvm/Support/DataTypes.h"
00019 #include <cstddef>
00020 #include <limits>
00021 
00022 namespace llvm {
00023 namespace sys {
00024 
00025 /// SwapByteOrder_16 - This function returns a byte-swapped representation of
00026 /// the 16-bit argument.
00027 inline uint16_t SwapByteOrder_16(uint16_t value) {
00028 #if defined(_MSC_VER) && !defined(_DEBUG)
00029   // The DLL version of the runtime lacks these functions (bug!?), but in a
00030   // release build they're replaced with BSWAP instructions anyway.
00031   return _byteswap_ushort(value);
00032 #else
00033   uint16_t Hi = value << 8;
00034   uint16_t Lo = value >> 8;
00035   return Hi | Lo;
00036 #endif
00037 }
00038 
00039 /// SwapByteOrder_32 - This function returns a byte-swapped representation of
00040 /// the 32-bit argument.
00041 inline uint32_t SwapByteOrder_32(uint32_t value) {
00042 #if defined(__llvm__) || \
00043 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
00044   return __builtin_bswap32(value);
00045 #elif defined(_MSC_VER) && !defined(_DEBUG)
00046   return _byteswap_ulong(value);
00047 #else
00048   uint32_t Byte0 = value & 0x000000FF;
00049   uint32_t Byte1 = value & 0x0000FF00;
00050   uint32_t Byte2 = value & 0x00FF0000;
00051   uint32_t Byte3 = value & 0xFF000000;
00052   return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
00053 #endif
00054 }
00055 
00056 /// SwapByteOrder_64 - This function returns a byte-swapped representation of
00057 /// the 64-bit argument.
00058 inline uint64_t SwapByteOrder_64(uint64_t value) {
00059 #if defined(__llvm__) || \
00060 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
00061   return __builtin_bswap64(value);
00062 #elif defined(_MSC_VER) && !defined(_DEBUG)
00063   return _byteswap_uint64(value);
00064 #else
00065   uint64_t Hi = SwapByteOrder_32(uint32_t(value));
00066   uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
00067   return (Hi << 32) | Lo;
00068 #endif
00069 }
00070 
00071 inline unsigned char  getSwappedBytes(unsigned char C) { return C; }
00072 inline   signed char  getSwappedBytes(signed char C) { return C; }
00073 inline          char  getSwappedBytes(char C) { return C; }
00074 
00075 inline unsigned short getSwappedBytes(unsigned short C) { return SwapByteOrder_16(C); }
00076 inline   signed short getSwappedBytes(  signed short C) { return SwapByteOrder_16(C); }
00077 
00078 inline unsigned int   getSwappedBytes(unsigned int   C) { return SwapByteOrder_32(C); }
00079 inline   signed int   getSwappedBytes(  signed int   C) { return SwapByteOrder_32(C); }
00080 
00081 #if __LONG_MAX__ == __INT_MAX__
00082 inline unsigned long  getSwappedBytes(unsigned long  C) { return SwapByteOrder_32(C); }
00083 inline   signed long  getSwappedBytes(  signed long  C) { return SwapByteOrder_32(C); }
00084 #elif __LONG_MAX__ == __LONG_LONG_MAX__
00085 inline unsigned long  getSwappedBytes(unsigned long  C) { return SwapByteOrder_64(C); }
00086 inline   signed long  getSwappedBytes(  signed long  C) { return SwapByteOrder_64(C); }
00087 #else
00088 #error "Unknown long size!"
00089 #endif
00090 
00091 inline unsigned long long getSwappedBytes(unsigned long long C) {
00092   return SwapByteOrder_64(C);
00093 }
00094 inline signed long long getSwappedBytes(signed long long C) {
00095   return SwapByteOrder_64(C);
00096 }
00097 
00098 template<typename T>
00099 inline void swapByteOrder(T &Value) {
00100   Value = getSwappedBytes(Value);
00101 }
00102 
00103 } // end namespace sys
00104 } // end namespace llvm
00105 
00106 #endif