SwapByteOrder.h revision 256281
11541Srgrimes//===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===// 21541Srgrimes// 31541Srgrimes// The LLVM Compiler Infrastructure 41541Srgrimes// 51541Srgrimes// This file is distributed under the University of Illinois Open Source 61541Srgrimes// License. See LICENSE.TXT for details. 71541Srgrimes// 81541Srgrimes//===----------------------------------------------------------------------===// 91541Srgrimes// 101541Srgrimes// This file declares generic and optimized functions to swap the byte order of 111541Srgrimes// an integral type. 121541Srgrimes// 131541Srgrimes//===----------------------------------------------------------------------===// 141541Srgrimes 151541Srgrimes#ifndef LLVM_SUPPORT_SWAPBYTEORDER_H 161541Srgrimes#define LLVM_SUPPORT_SWAPBYTEORDER_H 171541Srgrimes 181541Srgrimes#include "llvm/Support/DataTypes.h" 191541Srgrimes#include <cstddef> 201541Srgrimes#include <limits> 211541Srgrimes 221541Srgrimesnamespace llvm { 231541Srgrimesnamespace sys { 241541Srgrimes 251541Srgrimes/// SwapByteOrder_16 - This function returns a byte-swapped representation of 261541Srgrimes/// the 16-bit argument. 271541Srgrimesinline uint16_t SwapByteOrder_16(uint16_t value) { 281541Srgrimes#if defined(_MSC_VER) && !defined(_DEBUG) 291541Srgrimes // The DLL version of the runtime lacks these functions (bug!?), but in a 301541Srgrimes // release build they're replaced with BSWAP instructions anyway. 311541Srgrimes return _byteswap_ushort(value); 321541Srgrimes#else 331541Srgrimes uint16_t Hi = value << 8; 3413765Smpp uint16_t Lo = value >> 8; 351541Srgrimes return Hi | Lo; 361541Srgrimes#endif 371549Srgrimes} 381549Srgrimes 391549Srgrimes/// SwapByteOrder_32 - This function returns a byte-swapped representation of 401541Srgrimes/// the 32-bit argument. 411541Srgrimesinline uint32_t SwapByteOrder_32(uint32_t value) { 421541Srgrimes#if defined(__llvm__) || \ 431541Srgrimes(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC) 441541Srgrimes return __builtin_bswap32(value); 451541Srgrimes#elif defined(_MSC_VER) && !defined(_DEBUG) 461541Srgrimes return _byteswap_ulong(value); 471541Srgrimes#else 481541Srgrimes uint32_t Byte0 = value & 0x000000FF; 491541Srgrimes uint32_t Byte1 = value & 0x0000FF00; 501541Srgrimes uint32_t Byte2 = value & 0x00FF0000; 511541Srgrimes uint32_t Byte3 = value & 0xFF000000; 521541Srgrimes return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24); 531541Srgrimes#endif 541541Srgrimes} 551541Srgrimes 561541Srgrimes/// SwapByteOrder_64 - This function returns a byte-swapped representation of 571541Srgrimes/// the 64-bit argument. 581541Srgrimesinline uint64_t SwapByteOrder_64(uint64_t value) { 591541Srgrimes#if defined(__llvm__) || \ 601541Srgrimes(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC) 611541Srgrimes return __builtin_bswap64(value); 621549Srgrimes#elif defined(_MSC_VER) && !defined(_DEBUG) 631549Srgrimes return _byteswap_uint64(value); 641549Srgrimes#else 651549Srgrimes uint64_t Hi = SwapByteOrder_32(uint32_t(value)); 661549Srgrimes uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32)); 671549Srgrimes return (Hi << 32) | Lo; 681549Srgrimes#endif 691549Srgrimes} 701549Srgrimes 717217Sdufaultinline unsigned char SwapByteOrder(unsigned char C) { return C; } 7213765Smppinline signed char SwapByteOrder(signed char C) { return C; } 731549Srgrimesinline char SwapByteOrder(char C) { return C; } 741549Srgrimes 753963Sjkhinline unsigned short SwapByteOrder(unsigned short C) { return SwapByteOrder_16(C); } 767217Sdufaultinline signed short SwapByteOrder( signed short C) { return SwapByteOrder_16(C); } 7713347Sjoerg 787217Sdufaultinline unsigned int SwapByteOrder(unsigned int C) { return SwapByteOrder_32(C); } 7913347Sjoerginline signed int SwapByteOrder( signed int C) { return SwapByteOrder_32(C); } 803963Sjkh 811549Srgrimes#if __LONG_MAX__ == __INT_MAX__ 821549Srgrimesinline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_32(C); } 831541Srgrimesinline signed long SwapByteOrder( signed long C) { return SwapByteOrder_32(C); } 841541Srgrimes#elif __LONG_MAX__ == __LONG_LONG_MAX__ 851541Srgrimesinline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_64(C); } 861541Srgrimesinline signed long SwapByteOrder( signed long C) { return SwapByteOrder_64(C); } 871541Srgrimes#else 881541Srgrimes#error "Unknown long size!" 891541Srgrimes#endif 901541Srgrimes 911541Srgrimesinline unsigned long long SwapByteOrder(unsigned long long C) { 921549Srgrimes return SwapByteOrder_64(C); 937217Sdufault} 947217Sdufaultinline signed long long SwapByteOrder(signed long long C) { 9513765Smpp return SwapByteOrder_64(C); 961549Srgrimes} 971549Srgrimes 981549Srgrimes} // end namespace sys 991549Srgrimes} // end namespace llvm 1001549Srgrimes 1011549Srgrimes#endif 1021549Srgrimes