Home | History | Annotate | Download | only in Support
      1 //===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file declares generic and optimized functions to swap the byte order of
     11 // an integral type.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_SUPPORT_SWAPBYTEORDER_H
     16 #define LLVM_SUPPORT_SWAPBYTEORDER_H
     17 
     18 #include "llvm/Support/Compiler.h"
     19 #include "llvm/Support/DataTypes.h"
     20 #include <cstddef>
     21 #if defined(_MSC_VER) && !defined(_DEBUG)
     22 #include <stdlib.h>
     23 #endif
     24 
     25 namespace llvm {
     26 namespace sys {
     27 
     28 /// SwapByteOrder_16 - This function returns a byte-swapped representation of
     29 /// the 16-bit argument.
     30 inline uint16_t SwapByteOrder_16(uint16_t value) {
     31 #if defined(_MSC_VER) && !defined(_DEBUG)
     32   // The DLL version of the runtime lacks these functions (bug!?), but in a
     33   // release build they're replaced with BSWAP instructions anyway.
     34   return _byteswap_ushort(value);
     35 #else
     36   uint16_t Hi = value << 8;
     37   uint16_t Lo = value >> 8;
     38   return Hi | Lo;
     39 #endif
     40 }
     41 
     42 /// SwapByteOrder_32 - This function returns a byte-swapped representation of
     43 /// the 32-bit argument.
     44 inline uint32_t SwapByteOrder_32(uint32_t value) {
     45 #if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC))
     46   return __builtin_bswap32(value);
     47 #elif defined(_MSC_VER) && !defined(_DEBUG)
     48   return _byteswap_ulong(value);
     49 #else
     50   uint32_t Byte0 = value & 0x000000FF;
     51   uint32_t Byte1 = value & 0x0000FF00;
     52   uint32_t Byte2 = value & 0x00FF0000;
     53   uint32_t Byte3 = value & 0xFF000000;
     54   return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
     55 #endif
     56 }
     57 
     58 /// SwapByteOrder_64 - This function returns a byte-swapped representation of
     59 /// the 64-bit argument.
     60 inline uint64_t SwapByteOrder_64(uint64_t value) {
     61 #if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC))
     62   return __builtin_bswap64(value);
     63 #elif defined(_MSC_VER) && !defined(_DEBUG)
     64   return _byteswap_uint64(value);
     65 #else
     66   uint64_t Hi = SwapByteOrder_32(uint32_t(value));
     67   uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
     68   return (Hi << 32) | Lo;
     69 #endif
     70 }
     71 
     72 inline unsigned char  getSwappedBytes(unsigned char C) { return C; }
     73 inline   signed char  getSwappedBytes(signed char C) { return C; }
     74 inline          char  getSwappedBytes(char C) { return C; }
     75 
     76 inline unsigned short getSwappedBytes(unsigned short C) { return SwapByteOrder_16(C); }
     77 inline   signed short getSwappedBytes(  signed short C) { return SwapByteOrder_16(C); }
     78 
     79 inline unsigned int   getSwappedBytes(unsigned int   C) { return SwapByteOrder_32(C); }
     80 inline   signed int   getSwappedBytes(  signed int   C) { return SwapByteOrder_32(C); }
     81 
     82 #if __LONG_MAX__ == __INT_MAX__
     83 inline unsigned long  getSwappedBytes(unsigned long  C) { return SwapByteOrder_32(C); }
     84 inline   signed long  getSwappedBytes(  signed long  C) { return SwapByteOrder_32(C); }
     85 #elif __LONG_MAX__ == __LONG_LONG_MAX__
     86 inline unsigned long  getSwappedBytes(unsigned long  C) { return SwapByteOrder_64(C); }
     87 inline   signed long  getSwappedBytes(  signed long  C) { return SwapByteOrder_64(C); }
     88 #else
     89 #error "Unknown long size!"
     90 #endif
     91 
     92 inline unsigned long long getSwappedBytes(unsigned long long C) {
     93   return SwapByteOrder_64(C);
     94 }
     95 inline signed long long getSwappedBytes(signed long long C) {
     96   return SwapByteOrder_64(C);
     97 }
     98 
     99 inline float getSwappedBytes(float C) {
    100   union {
    101     uint32_t i;
    102     float f;
    103   } in, out;
    104   in.f = C;
    105   out.i = SwapByteOrder_32(in.i);
    106   return out.f;
    107 }
    108 
    109 inline double getSwappedBytes(double C) {
    110   union {
    111     uint64_t i;
    112     double d;
    113   } in, out;
    114   in.d = C;
    115   out.i = SwapByteOrder_64(in.i);
    116   return out.d;
    117 }
    118 
    119 template<typename T>
    120 inline void swapByteOrder(T &Value) {
    121   Value = getSwappedBytes(Value);
    122 }
    123 
    124 } // end namespace sys
    125 } // end namespace llvm
    126 
    127 #endif
    128