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