byteswap.hh revision 5549
15245Sgblack@eecs.umich.edu/* 25245Sgblack@eecs.umich.edu * Copyright (c) 2004 The Regents of The University of Michigan 35245Sgblack@eecs.umich.edu * All rights reserved. 45245Sgblack@eecs.umich.edu * 57087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 67087Snate@binkert.org * modification, are permitted provided that the following conditions are 77087Snate@binkert.org * met: redistributions of source code must retain the above copyright 87087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 97087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 107087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 117087Snate@binkert.org * documentation and/or other materials provided with the distribution; 127087Snate@binkert.org * neither the name of the copyright holders nor the names of its 135245Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147087Snate@binkert.org * this software without specific prior written permission. 157087Snate@binkert.org * 167087Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177087Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187087Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197087Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207087Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217087Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225245Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237087Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245245Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255245Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265245Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275245Sgblack@eecs.umich.edu * 285245Sgblack@eecs.umich.edu * Authors: Gabe Black 295245Sgblack@eecs.umich.edu * Ali Saidi 305245Sgblack@eecs.umich.edu * Nathan Binkert 315245Sgblack@eecs.umich.edu */ 325245Sgblack@eecs.umich.edu 335245Sgblack@eecs.umich.edu//The purpose of this file is to provide endainness conversion utility 345245Sgblack@eecs.umich.edu//functions. Depending on the endianness of the guest system, either 355245Sgblack@eecs.umich.edu//the LittleEndianGuest or BigEndianGuest namespace is used. 365245Sgblack@eecs.umich.edu 375245Sgblack@eecs.umich.edu#ifndef __SIM_BYTE_SWAP_HH__ 385245Sgblack@eecs.umich.edu#define __SIM_BYTE_SWAP_HH__ 395245Sgblack@eecs.umich.edu 405245Sgblack@eecs.umich.edu#include "base/bigint.hh" 415245Sgblack@eecs.umich.edu#include "base/misc.hh" 425245Sgblack@eecs.umich.edu#include "sim/host.hh" 435245Sgblack@eecs.umich.edu 445245Sgblack@eecs.umich.edu// This lets us figure out what the byte order of the host system is 455245Sgblack@eecs.umich.edu#if defined(linux) 465245Sgblack@eecs.umich.edu#include <endian.h> 476216Snate@binkert.org// If this is a linux system, lets used the optimized definitions if they exist. 485245Sgblack@eecs.umich.edu// If one doesn't exist, we pretty much get what is listed below, so it all 495245Sgblack@eecs.umich.edu// works out 505245Sgblack@eecs.umich.edu#include <byteswap.h> 517901Shestness@cs.utexas.edu#elif defined (__sun) 528832SAli.Saidi@ARM.com#include <sys/isa_defs.h> 535245Sgblack@eecs.umich.edu#else 545245Sgblack@eecs.umich.edu#include <machine/endian.h> 555245Sgblack@eecs.umich.edu#endif 565245Sgblack@eecs.umich.edu 575245Sgblack@eecs.umich.edu#if defined(__APPLE__) 585245Sgblack@eecs.umich.edu#include <libkern/OSByteOrder.h> 595245Sgblack@eecs.umich.edu#endif 605245Sgblack@eecs.umich.edu 617912Shestness@cs.utexas.eduenum ByteOrder {BigEndianByteOrder, LittleEndianByteOrder}; 628922Swilliam.wang@arm.com 635245Sgblack@eecs.umich.edu//These functions actually perform the swapping for parameters 645245Sgblack@eecs.umich.edu//of various bit lengths 655245Sgblack@eecs.umich.eduinline uint64_t 668922Swilliam.wang@arm.comswap_byte64(uint64_t x) 675245Sgblack@eecs.umich.edu{ 685245Sgblack@eecs.umich.edu#if defined(linux) 695245Sgblack@eecs.umich.edu return bswap_64(x); 708832SAli.Saidi@ARM.com#elif defined(__APPLE__) 715245Sgblack@eecs.umich.edu return OSSwapInt64(x); 728975Sandreas.hansson@arm.com#else 7310713Sandreas.hansson@arm.com return (uint64_t)((((uint64_t)(x) & 0xff) << 56) | 745245Sgblack@eecs.umich.edu ((uint64_t)(x) & 0xff00ULL) << 40 | 755245Sgblack@eecs.umich.edu ((uint64_t)(x) & 0xff0000ULL) << 24 | 767912Shestness@cs.utexas.edu ((uint64_t)(x) & 0xff000000ULL) << 8 | 777912Shestness@cs.utexas.edu ((uint64_t)(x) & 0xff00000000ULL) >> 8 | 785245Sgblack@eecs.umich.edu ((uint64_t)(x) & 0xff0000000000ULL) >> 24 | 797912Shestness@cs.utexas.edu ((uint64_t)(x) & 0xff000000000000ULL) >> 40 | 809044SAli.Saidi@ARM.com ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) ; 817912Shestness@cs.utexas.edu#endif 829701Sgedare@rtems.org} 837912Shestness@cs.utexas.edu 847912Shestness@cs.utexas.eduinline uint32_t 857912Shestness@cs.utexas.eduswap_byte32(uint32_t x) 867912Shestness@cs.utexas.edu{ 877912Shestness@cs.utexas.edu#if defined(linux) 887912Shestness@cs.utexas.edu return bswap_32(x); 897912Shestness@cs.utexas.edu#elif defined(__APPLE__) 907912Shestness@cs.utexas.edu return OSSwapInt32(x); 917912Shestness@cs.utexas.edu#else 927912Shestness@cs.utexas.edu return (uint32_t)(((uint32_t)(x) & 0xff) << 24 | 937912Shestness@cs.utexas.edu ((uint32_t)(x) & 0xff00) << 8 | ((uint32_t)(x) & 0xff0000) >> 8 | 945245Sgblack@eecs.umich.edu ((uint32_t)(x) & 0xff000000) >> 24); 957912Shestness@cs.utexas.edu#endif 968832SAli.Saidi@ARM.com} 977912Shestness@cs.utexas.edu 987912Shestness@cs.utexas.eduinline uint16_t 997912Shestness@cs.utexas.eduswap_byte16(uint16_t x) 1007912Shestness@cs.utexas.edu{ 1017912Shestness@cs.utexas.edu#if defined(linux) 1027912Shestness@cs.utexas.edu return bswap_16(x); 1037912Shestness@cs.utexas.edu#elif defined(__APPLE__) 1047912Shestness@cs.utexas.edu return OSSwapInt16(x); 1057912Shestness@cs.utexas.edu#else 1067912Shestness@cs.utexas.edu return (uint16_t)(((uint16_t)(x) & 0xff) << 8 | 1077912Shestness@cs.utexas.edu ((uint16_t)(x) & 0xff00) >> 8); 1087912Shestness@cs.utexas.edu#endif 1097912Shestness@cs.utexas.edu} 1107912Shestness@cs.utexas.edu 1117912Shestness@cs.utexas.edu// This function lets the compiler figure out how to call the 1127912Shestness@cs.utexas.edu// swap_byte functions above for different data types. Since the 1137912Shestness@cs.utexas.edu// sizeof() values are known at compile time, it should inline to a 1147912Shestness@cs.utexas.edu// direct call to the right swap_byteNN() function. 1157912Shestness@cs.utexas.edutemplate <typename T> 1167912Shestness@cs.utexas.eduinline T swap_byte(T x) { 1177912Shestness@cs.utexas.edu if (sizeof(T) == 8) 1187912Shestness@cs.utexas.edu return swap_byte64((uint64_t)x); 1197912Shestness@cs.utexas.edu else if (sizeof(T) == 4) 1207912Shestness@cs.utexas.edu return swap_byte32((uint32_t)x); 1217912Shestness@cs.utexas.edu else if (sizeof(T) == 2) 1227912Shestness@cs.utexas.edu return swap_byte16((uint16_t)x); 1237912Shestness@cs.utexas.edu else if (sizeof(T) == 1) 1247912Shestness@cs.utexas.edu return x; 1257912Shestness@cs.utexas.edu else 1267912Shestness@cs.utexas.edu panic("Can't byte-swap values larger than 64 bits"); 1278953Sgblack@eecs.umich.edu} 1287912Shestness@cs.utexas.edu 1297912Shestness@cs.utexas.edutemplate<> 1307912Shestness@cs.utexas.eduinline Twin64_t swap_byte<Twin64_t>(Twin64_t x) 1317912Shestness@cs.utexas.edu{ 1327912Shestness@cs.utexas.edu x.a = swap_byte(x.a); 1337912Shestness@cs.utexas.edu x.b = swap_byte(x.b); 1347912Shestness@cs.utexas.edu return x; 1357912Shestness@cs.utexas.edu} 1367912Shestness@cs.utexas.edu 1377912Shestness@cs.utexas.edutemplate<> 1387912Shestness@cs.utexas.eduinline Twin32_t swap_byte<Twin32_t>(Twin32_t x) 1397912Shestness@cs.utexas.edu{ 1407912Shestness@cs.utexas.edu x.a = swap_byte(x.a); 1417912Shestness@cs.utexas.edu x.b = swap_byte(x.b); 1427912Shestness@cs.utexas.edu return x; 1437912Shestness@cs.utexas.edu} 1447912Shestness@cs.utexas.edu 1457912Shestness@cs.utexas.edu//The conversion functions with fixed endianness on both ends don't need to 1467912Shestness@cs.utexas.edu//be in a namespace 1477912Shestness@cs.utexas.edutemplate <typename T> inline T betole(T value) {return swap_byte(value);} 1487912Shestness@cs.utexas.edutemplate <typename T> inline T letobe(T value) {return swap_byte(value);} 1497912Shestness@cs.utexas.edu 1507912Shestness@cs.utexas.edu//For conversions not involving the guest system, we can define the functions 1517912Shestness@cs.utexas.edu//conditionally based on the BYTE_ORDER macro and outside of the namespaces 1527912Shestness@cs.utexas.edu#if defined(_BIG_ENDIAN) || !defined(_LITTLE_ENDIAN) && BYTE_ORDER == BIG_ENDIAN 1539542Sandreas.hansson@arm.comconst ByteOrder HostByteOrder = BigEndianByteOrder; 1549542Sandreas.hansson@arm.comtemplate <typename T> inline T htole(T value) {return swap_byte(value);} 1557912Shestness@cs.utexas.edutemplate <typename T> inline T letoh(T value) {return swap_byte(value);} 1567912Shestness@cs.utexas.edutemplate <typename T> inline T htobe(T value) {return value;} 1577912Shestness@cs.utexas.edutemplate <typename T> inline T betoh(T value) {return value;} 1587912Shestness@cs.utexas.edu#elif defined(_LITTLE_ENDIAN) || BYTE_ORDER == LITTLE_ENDIAN 1597912Shestness@cs.utexas.educonst ByteOrder HostByteOrder = LittleEndianByteOrder; 1607912Shestness@cs.utexas.edutemplate <typename T> inline T htole(T value) {return value;} 1617912Shestness@cs.utexas.edutemplate <typename T> inline T letoh(T value) {return value;} 1628953Sgblack@eecs.umich.edutemplate <typename T> inline T htobe(T value) {return swap_byte(value);} 1639294Sandreas.hansson@arm.comtemplate <typename T> inline T betoh(T value) {return swap_byte(value);} 1649294Sandreas.hansson@arm.com#else 1657912Shestness@cs.utexas.edu #error Invalid Endianess 1667912Shestness@cs.utexas.edu#endif 1675245Sgblack@eecs.umich.edu 1685245Sgblack@eecs.umich.edunamespace BigEndianGuest 1695245Sgblack@eecs.umich.edu{ 1708832SAli.Saidi@ARM.com const bool ByteOrderDiffers = (HostByteOrder != BigEndianByteOrder); 1715245Sgblack@eecs.umich.edu template <typename T> 1729701Sgedare@rtems.org inline T gtole(T value) {return betole(value);} 1739701Sgedare@rtems.org template <typename T> 1749701Sgedare@rtems.org inline T letog(T value) {return letobe(value);} 1759701Sgedare@rtems.org template <typename T> 1769701Sgedare@rtems.org inline T gtobe(T value) {return value;} 1779701Sgedare@rtems.org template <typename T> 17810654Sandreas.hansson@arm.com inline T betog(T value) {return value;} 17910654Sandreas.hansson@arm.com template <typename T> 18010654Sandreas.hansson@arm.com inline T htog(T value) {return htobe(value);} 18112088Sspwilson2@wisc.edu template <typename T> 18210654Sandreas.hansson@arm.com inline T gtoh(T value) {return betoh(value);} 1837912Shestness@cs.utexas.edu} 1848975Sandreas.hansson@arm.com 18510713Sandreas.hansson@arm.comnamespace LittleEndianGuest 1867912Shestness@cs.utexas.edu{ 1875245Sgblack@eecs.umich.edu const bool ByteOrderDiffers = (HostByteOrder != LittleEndianByteOrder); 1885245Sgblack@eecs.umich.edu template <typename T> 1895245Sgblack@eecs.umich.edu inline T gtole(T value) {return value;} 1905245Sgblack@eecs.umich.edu template <typename T> 1915245Sgblack@eecs.umich.edu inline T letog(T value) {return value;} 1925245Sgblack@eecs.umich.edu template <typename T> 1935245Sgblack@eecs.umich.edu inline T gtobe(T value) {return letobe(value);} 1945245Sgblack@eecs.umich.edu template <typename T> 1955245Sgblack@eecs.umich.edu inline T betog(T value) {return betole(value);} 1965245Sgblack@eecs.umich.edu template <typename T> 1978832SAli.Saidi@ARM.com inline T htog(T value) {return htole(value);} 1988832SAli.Saidi@ARM.com template <typename T> 1998832SAli.Saidi@ARM.com inline T gtoh(T value) {return letoh(value);} 2008832SAli.Saidi@ARM.com} 2018832SAli.Saidi@ARM.com#endif // __SIM_BYTE_SWAP_HH__ 2028832SAli.Saidi@ARM.com