LLVM API Documentation
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