byteswap.hh revision 2483
15086Sgblack@eecs.umich.edu/* 25086Sgblack@eecs.umich.edu * Copyright (c) 2004 The Regents of The University of Michigan 35086Sgblack@eecs.umich.edu * All rights reserved. 45086Sgblack@eecs.umich.edu * 55086Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 65086Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 75086Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 85086Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 95086Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 105086Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 115086Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 125086Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 135086Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 145086Sgblack@eecs.umich.edu * this software without specific prior written permission. 155086Sgblack@eecs.umich.edu * 165086Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175086Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185086Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195086Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205086Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215086Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225086Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235086Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245086Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255086Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265086Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275086Sgblack@eecs.umich.edu */ 285086Sgblack@eecs.umich.edu 295086Sgblack@eecs.umich.edu//The purpose of this file is to provide endainness conversion utility 305086Sgblack@eecs.umich.edu//functions. Depending on the endianness of the guest system, either 315086Sgblack@eecs.umich.edu//the LittleEndianGuest or BigEndianGuest namespace is used. 325086Sgblack@eecs.umich.edu 335086Sgblack@eecs.umich.edu#ifndef __SIM_BYTE_SWAP_HH__ 345086Sgblack@eecs.umich.edu#define __SIM_BYTE_SWAP_HH__ 355086Sgblack@eecs.umich.edu 365086Sgblack@eecs.umich.edu#include "sim/host.hh" 375086Sgblack@eecs.umich.edu 385086Sgblack@eecs.umich.edu// This lets us figure out what the byte order of the host system is 395086Sgblack@eecs.umich.edu#if defined(linux) 405086Sgblack@eecs.umich.edu#include <endian.h> 415086Sgblack@eecs.umich.edu#else 425086Sgblack@eecs.umich.edu#include <machine/endian.h> 435086Sgblack@eecs.umich.edu#endif 445086Sgblack@eecs.umich.edu 455086Sgblack@eecs.umich.edu//These functions actually perform the swapping for parameters 465086Sgblack@eecs.umich.edu//of various bit lengths 475086Sgblack@eecs.umich.edustatic inline uint64_t 485086Sgblack@eecs.umich.eduswap_byte64(uint64_t x) 495086Sgblack@eecs.umich.edu{ 505086Sgblack@eecs.umich.edu return (uint64_t)((((uint64_t)(x) & 0xff) << 56) | 515086Sgblack@eecs.umich.edu ((uint64_t)(x) & 0xff00ULL) << 40 | 525086Sgblack@eecs.umich.edu ((uint64_t)(x) & 0xff0000ULL) << 24 | 535086Sgblack@eecs.umich.edu ((uint64_t)(x) & 0xff000000ULL) << 8 | 545086Sgblack@eecs.umich.edu ((uint64_t)(x) & 0xff00000000ULL) >> 8 | 555086Sgblack@eecs.umich.edu ((uint64_t)(x) & 0xff0000000000ULL) >> 24 | 565086Sgblack@eecs.umich.edu ((uint64_t)(x) & 0xff000000000000ULL) >> 40 | 575086Sgblack@eecs.umich.edu ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) ; 585135Sgblack@eecs.umich.edu} 595135Sgblack@eecs.umich.edu 605135Sgblack@eecs.umich.edustatic inline uint32_t 615086Sgblack@eecs.umich.eduswap_byte32(uint32_t x) 625135Sgblack@eecs.umich.edu{ 635086Sgblack@eecs.umich.edu return (uint32_t)(((uint32_t)(x) & 0xff) << 24 | 645086Sgblack@eecs.umich.edu ((uint32_t)(x) & 0xff00) << 8 | ((uint32_t)(x) & 0xff0000) >> 8 | 655086Sgblack@eecs.umich.edu ((uint32_t)(x) & 0xff000000) >> 24); 665086Sgblack@eecs.umich.edu 675086Sgblack@eecs.umich.edu} 685086Sgblack@eecs.umich.edu 695086Sgblack@eecs.umich.edustatic inline uint16_t 705086Sgblack@eecs.umich.eduswap_byte16(uint16_t x) 715086Sgblack@eecs.umich.edu{ 725086Sgblack@eecs.umich.edu return (uint16_t)(((uint16_t)(x) & 0xff) << 8 | 735086Sgblack@eecs.umich.edu ((uint16_t)(x) & 0xff00) >> 8); 745135Sgblack@eecs.umich.edu} 755135Sgblack@eecs.umich.edu 765135Sgblack@eecs.umich.edu//This lets the compiler figure out how to call the swap_byte functions above 775135Sgblack@eecs.umich.edu//for different data types. 785135Sgblack@eecs.umich.edustatic inline uint64_t swap_byte(uint64_t x) {return swap_byte64(x);} 795135Sgblack@eecs.umich.edustatic inline int64_t swap_byte(int64_t x) {return swap_byte64((uint64_t)x);} 805135Sgblack@eecs.umich.edustatic inline uint32_t swap_byte(uint32_t x) {return swap_byte32(x);} 815135Sgblack@eecs.umich.edustatic inline int32_t swap_byte(int32_t x) {return swap_byte32((uint32_t)x);} 825135Sgblack@eecs.umich.edu//This is to prevent the following two functions from compiling on 835135Sgblack@eecs.umich.edu//64bit machines. It won't detect everything, so it should be changed. 845135Sgblack@eecs.umich.edu#ifndef __x86_64__ 855135Sgblack@eecs.umich.edustatic inline long swap_byte(long x) {return swap_byte32((long)x);} 865135Sgblack@eecs.umich.edustatic inline unsigned long swap_byte(unsigned long x) 875135Sgblack@eecs.umich.edu { return swap_byte32((unsigned long)x);} 885135Sgblack@eecs.umich.edu#endif 895135Sgblack@eecs.umich.edustatic inline uint16_t swap_byte(uint16_t x) {return swap_byte32(x);} 905135Sgblack@eecs.umich.edustatic inline int16_t swap_byte(int16_t x) {return swap_byte16((uint16_t)x);} 915135Sgblack@eecs.umich.edustatic inline uint8_t swap_byte(uint8_t x) {return x;} 925135Sgblack@eecs.umich.edustatic inline int8_t swap_byte(int8_t x) {return x;} 935135Sgblack@eecs.umich.edustatic inline double swap_byte(double x) {return swap_byte64((uint64_t)x);} 945135Sgblack@eecs.umich.edustatic inline float swap_byte(float x) {return swap_byte32((uint32_t)x);} 955135Sgblack@eecs.umich.edu 965135Sgblack@eecs.umich.edu//The conversion functions with fixed endianness on both ends don't need to 975135Sgblack@eecs.umich.edu//be in a namespace 985135Sgblack@eecs.umich.edutemplate <typename T> static inline T betole(T value) {return swap_byte(value);} 995135Sgblack@eecs.umich.edutemplate <typename T> static inline T letobe(T value) {return swap_byte(value);} 1005135Sgblack@eecs.umich.edu 1015135Sgblack@eecs.umich.edu//For conversions not involving the guest system, we can define the functions 1025135Sgblack@eecs.umich.edu//conditionally based on the BYTE_ORDER macro and outside of the namespaces 1035135Sgblack@eecs.umich.edu#if BYTE_ORDER == BIG_ENDIAN 1045135Sgblack@eecs.umich.edutemplate <typename T> static inline T htole(T value) {return swap_byte(value);} 1055135Sgblack@eecs.umich.edutemplate <typename T> static inline T letoh(T value) {return swap_byte(value);} 1065135Sgblack@eecs.umich.edutemplate <typename T> static inline T htobe(T value) {return value;} 1075135Sgblack@eecs.umich.edutemplate <typename T> static inline T betoh(T value) {return value;} 1085135Sgblack@eecs.umich.edu#elif BYTE_ORDER == LITTLE_ENDIAN 1095135Sgblack@eecs.umich.edutemplate <typename T> static inline T htole(T value) {return value;} 1105141Sgblack@eecs.umich.edutemplate <typename T> static inline T letoh(T value) {return value;} 1115141Sgblack@eecs.umich.edutemplate <typename T> static inline T htobe(T value) {return swap_byte(value);} 1125141Sgblack@eecs.umich.edutemplate <typename T> static inline T betoh(T value) {return swap_byte(value);} 1135141Sgblack@eecs.umich.edu#else 1145141Sgblack@eecs.umich.edu #error Invalid Endianess 1155141Sgblack@eecs.umich.edu#endif 1165141Sgblack@eecs.umich.edu 1175135Sgblack@eecs.umich.edunamespace BigEndianGuest 1185135Sgblack@eecs.umich.edu{ 1195135Sgblack@eecs.umich.edu template <typename T> 1205135Sgblack@eecs.umich.edu static inline T gtole(T value) {return betole(value);} 1215141Sgblack@eecs.umich.edu template <typename T> 1225135Sgblack@eecs.umich.edu static inline T letog(T value) {return letobe(value);} 1235135Sgblack@eecs.umich.edu template <typename T> 1245141Sgblack@eecs.umich.edu static inline T gtobe(T value) {return value;} 1255141Sgblack@eecs.umich.edu template <typename T> 1265141Sgblack@eecs.umich.edu static inline T betog(T value) {return value;} 1275141Sgblack@eecs.umich.edu template <typename T> 1285141Sgblack@eecs.umich.edu static inline T htog(T value) {return htobe(value);} 1295141Sgblack@eecs.umich.edu template <typename T> 1305141Sgblack@eecs.umich.edu static inline T gtoh(T value) {return betoh(value);} 1315135Sgblack@eecs.umich.edu} 1325135Sgblack@eecs.umich.edu 1335135Sgblack@eecs.umich.edunamespace LittleEndianGuest 1345135Sgblack@eecs.umich.edu{ 1355141Sgblack@eecs.umich.edu template <typename T> 1365135Sgblack@eecs.umich.edu static inline T gtole(T value) {return value;} 1375135Sgblack@eecs.umich.edu template <typename T> 1385135Sgblack@eecs.umich.edu static inline T letog(T value) {return value;} 1395135Sgblack@eecs.umich.edu template <typename T> 1405135Sgblack@eecs.umich.edu static inline T gtobe(T value) {return letobe(value);} 1415135Sgblack@eecs.umich.edu template <typename T> 1425135Sgblack@eecs.umich.edu static inline T betog(T value) {return betole(value);} 1435135Sgblack@eecs.umich.edu template <typename T> 1445135Sgblack@eecs.umich.edu static inline T htog(T value) {return htole(value);} 1455135Sgblack@eecs.umich.edu template <typename T> 1465135Sgblack@eecs.umich.edu static inline T gtoh(T value) {return letoh(value);} 1475135Sgblack@eecs.umich.edu} 1485135Sgblack@eecs.umich.edu#endif // __SIM_BYTE_SWAP_HH__ 1495135Sgblack@eecs.umich.edu