14c099b8724abf993262366e2a871004a2777becbMichael J. Spencer//===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===// 24c099b8724abf993262366e2a871004a2777becbMichael J. Spencer// 34c099b8724abf993262366e2a871004a2777becbMichael J. Spencer// The LLVM Compiler Infrastructure 44c099b8724abf993262366e2a871004a2777becbMichael J. Spencer// 54c099b8724abf993262366e2a871004a2777becbMichael J. Spencer// This file is distributed under the University of Illinois Open Source 64c099b8724abf993262366e2a871004a2777becbMichael J. Spencer// License. See LICENSE.TXT for details. 74c099b8724abf993262366e2a871004a2777becbMichael J. Spencer// 84c099b8724abf993262366e2a871004a2777becbMichael J. Spencer//===----------------------------------------------------------------------===// 94c099b8724abf993262366e2a871004a2777becbMichael J. Spencer// 104c099b8724abf993262366e2a871004a2777becbMichael J. Spencer// This file declares generic and optimized functions to swap the byte order of 114c099b8724abf993262366e2a871004a2777becbMichael J. Spencer// an integral type. 124c099b8724abf993262366e2a871004a2777becbMichael J. Spencer// 134c099b8724abf993262366e2a871004a2777becbMichael J. Spencer//===----------------------------------------------------------------------===// 144c099b8724abf993262366e2a871004a2777becbMichael J. Spencer 15674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#ifndef LLVM_SUPPORT_SWAPBYTEORDER_H 16674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#define LLVM_SUPPORT_SWAPBYTEORDER_H 174c099b8724abf993262366e2a871004a2777becbMichael J. Spencer 1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Compiler.h" 191f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DataTypes.h" 204c099b8724abf993262366e2a871004a2777becbMichael J. Spencer#include <cstddef> 214c099b8724abf993262366e2a871004a2777becbMichael J. Spencer 224c099b8724abf993262366e2a871004a2777becbMichael J. Spencernamespace llvm { 234c099b8724abf993262366e2a871004a2777becbMichael J. Spencernamespace sys { 244c099b8724abf993262366e2a871004a2777becbMichael J. Spencer 253afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner/// SwapByteOrder_16 - This function returns a byte-swapped representation of 263afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner/// the 16-bit argument. 273afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattnerinline uint16_t SwapByteOrder_16(uint16_t value) { 284c099b8724abf993262366e2a871004a2777becbMichael J. Spencer#if defined(_MSC_VER) && !defined(_DEBUG) 294c099b8724abf993262366e2a871004a2777becbMichael J. Spencer // The DLL version of the runtime lacks these functions (bug!?), but in a 304c099b8724abf993262366e2a871004a2777becbMichael J. Spencer // release build they're replaced with BSWAP instructions anyway. 314c099b8724abf993262366e2a871004a2777becbMichael J. Spencer return _byteswap_ushort(value); 324c099b8724abf993262366e2a871004a2777becbMichael J. Spencer#else 334c099b8724abf993262366e2a871004a2777becbMichael J. Spencer uint16_t Hi = value << 8; 344c099b8724abf993262366e2a871004a2777becbMichael J. Spencer uint16_t Lo = value >> 8; 353afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner return Hi | Lo; 364c099b8724abf993262366e2a871004a2777becbMichael J. Spencer#endif 374c099b8724abf993262366e2a871004a2777becbMichael J. Spencer} 384c099b8724abf993262366e2a871004a2777becbMichael J. Spencer 393afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner/// SwapByteOrder_32 - This function returns a byte-swapped representation of 403afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner/// the 32-bit argument. 413afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattnerinline uint32_t SwapByteOrder_32(uint32_t value) { 4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC)) 434c099b8724abf993262366e2a871004a2777becbMichael J. Spencer return __builtin_bswap32(value); 444c099b8724abf993262366e2a871004a2777becbMichael J. Spencer#elif defined(_MSC_VER) && !defined(_DEBUG) 454c099b8724abf993262366e2a871004a2777becbMichael J. Spencer return _byteswap_ulong(value); 464c099b8724abf993262366e2a871004a2777becbMichael J. Spencer#else 474c099b8724abf993262366e2a871004a2777becbMichael J. Spencer uint32_t Byte0 = value & 0x000000FF; 484c099b8724abf993262366e2a871004a2777becbMichael J. Spencer uint32_t Byte1 = value & 0x0000FF00; 494c099b8724abf993262366e2a871004a2777becbMichael J. Spencer uint32_t Byte2 = value & 0x00FF0000; 504c099b8724abf993262366e2a871004a2777becbMichael J. Spencer uint32_t Byte3 = value & 0xFF000000; 513afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24); 524c099b8724abf993262366e2a871004a2777becbMichael J. Spencer#endif 534c099b8724abf993262366e2a871004a2777becbMichael J. Spencer} 544c099b8724abf993262366e2a871004a2777becbMichael J. Spencer 553afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner/// SwapByteOrder_64 - This function returns a byte-swapped representation of 563afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner/// the 64-bit argument. 573afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattnerinline uint64_t SwapByteOrder_64(uint64_t value) { 5837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC)) 594c099b8724abf993262366e2a871004a2777becbMichael J. Spencer return __builtin_bswap64(value); 604c099b8724abf993262366e2a871004a2777becbMichael J. Spencer#elif defined(_MSC_VER) && !defined(_DEBUG) 614c099b8724abf993262366e2a871004a2777becbMichael J. Spencer return _byteswap_uint64(value); 624c099b8724abf993262366e2a871004a2777becbMichael J. Spencer#else 6392267bb35a75fc83fe3c0302e9fce031a3f817ffChris Lattner uint64_t Hi = SwapByteOrder_32(uint32_t(value)); 6492267bb35a75fc83fe3c0302e9fce031a3f817ffChris Lattner uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32)); 653afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner return (Hi << 32) | Lo; 663afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner#endif 673afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner} 683afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner 69c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline unsigned char getSwappedBytes(unsigned char C) { return C; } 70c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline signed char getSwappedBytes(signed char C) { return C; } 71c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline char getSwappedBytes(char C) { return C; } 723afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner 73c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline unsigned short getSwappedBytes(unsigned short C) { return SwapByteOrder_16(C); } 74c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline signed short getSwappedBytes( signed short C) { return SwapByteOrder_16(C); } 753afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner 76c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline unsigned int getSwappedBytes(unsigned int C) { return SwapByteOrder_32(C); } 77c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline signed int getSwappedBytes( signed int C) { return SwapByteOrder_32(C); } 783afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner 793afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner#if __LONG_MAX__ == __INT_MAX__ 80c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_32(C); } 81c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline signed long getSwappedBytes( signed long C) { return SwapByteOrder_32(C); } 823afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner#elif __LONG_MAX__ == __LONG_LONG_MAX__ 83c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_64(C); } 84c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline signed long getSwappedBytes( signed long C) { return SwapByteOrder_64(C); } 853afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner#else 863afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner#error "Unknown long size!" 874c099b8724abf993262366e2a871004a2777becbMichael J. Spencer#endif 881f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 89c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline unsigned long long getSwappedBytes(unsigned long long C) { 903afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner return SwapByteOrder_64(C); 913afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner} 92c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline signed long long getSwappedBytes(signed long long C) { 933afc385042fb0d121e9454347f975e4f1a5f5bfdChris Lattner return SwapByteOrder_64(C); 944c099b8724abf993262366e2a871004a2777becbMichael J. Spencer} 954c099b8724abf993262366e2a871004a2777becbMichael J. Spencer 96ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesinline float getSwappedBytes(float C) { 97ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines union { 98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t i; 99ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines float f; 100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } in, out; 101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines in.f = C; 102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines out.i = SwapByteOrder_32(in.i); 103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return out.f; 104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarinline double getSwappedBytes(double C) { 107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines union { 108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint64_t i; 109ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines double d; 110ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } in, out; 111ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines in.d = C; 112ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines out.i = SwapByteOrder_64(in.i); 113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return out.d; 114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 116c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate<typename T> 117c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesinline void swapByteOrder(T &Value) { 118c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Value = getSwappedBytes(Value); 119c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 120c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1214c099b8724abf993262366e2a871004a2777becbMichael J. Spencer} // end namespace sys 1224c099b8724abf993262366e2a871004a2777becbMichael J. Spencer} // end namespace llvm 1234c099b8724abf993262366e2a871004a2777becbMichael J. Spencer 1244c099b8724abf993262366e2a871004a2777becbMichael J. Spencer#endif 125