/*
 * Copyright (c) 2004 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 *          Ali Saidi
 *          Nathan Binkert
 */

//The purpose of this file is to provide endainness conversion utility
//functions. Depending on the endianness of the guest system, either
//the LittleEndianGuest or BigEndianGuest namespace is used.

#ifndef __SIM_BYTE_SWAP_HH__
#define __SIM_BYTE_SWAP_HH__

#include "base/bigint.hh"
#include "base/misc.hh"
#include "sim/host.hh"

// This lets us figure out what the byte order of the host system is
#if defined(linux)
#include <endian.h>
// If this is a linux system, lets used the optimized definitions if they exist.
// If one doesn't exist, we pretty much get what is listed below, so it all
// works out
#include <byteswap.h>
#elif defined (__sun)
#include <sys/isa_defs.h>
#else
#include <machine/endian.h>
#endif

#if defined(__APPLE__)
#include <libkern/OSByteOrder.h>
#endif

enum ByteOrder {BigEndianByteOrder, LittleEndianByteOrder};

//These functions actually perform the swapping for parameters
//of various bit lengths
static inline uint64_t
swap_byte64(uint64_t x)
{
#if defined(linux)
    return bswap_64(x);
#elif defined(__APPLE__)
    return OSSwapInt64(x);
#else
    return  (uint64_t)((((uint64_t)(x) & 0xff) << 56) |
            ((uint64_t)(x) & 0xff00ULL) << 40 |
            ((uint64_t)(x) & 0xff0000ULL) << 24 |
            ((uint64_t)(x) & 0xff000000ULL) << 8 |
            ((uint64_t)(x) & 0xff00000000ULL) >> 8 |
            ((uint64_t)(x) & 0xff0000000000ULL) >> 24 |
            ((uint64_t)(x) & 0xff000000000000ULL) >> 40 |
            ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) ;
#endif
}

static inline uint32_t
swap_byte32(uint32_t x)
{
#if defined(linux)
    return bswap_32(x);
#elif defined(__APPLE__)
    return OSSwapInt32(x);
#else
    return  (uint32_t)(((uint32_t)(x) & 0xff) << 24 |
            ((uint32_t)(x) & 0xff00) << 8 | ((uint32_t)(x) & 0xff0000) >> 8 |
            ((uint32_t)(x) & 0xff000000) >> 24);
#endif
}

static inline uint16_t
swap_byte16(uint16_t x)
{
#if defined(linux)
    return bswap_16(x);
#elif defined(__APPLE__)
    return OSSwapInt16(x);
#else
    return (uint16_t)(((uint16_t)(x) & 0xff) << 8 |
                      ((uint16_t)(x) & 0xff00) >> 8);
#endif
}

// This function lets the compiler figure out how to call the
// swap_byte functions above for different data types.  Since the
// sizeof() values are known at compile time, it should inline to a
// direct call to the right swap_byteNN() function.
template <typename T>
static inline T swap_byte(T x) {
    if (sizeof(T) == 8)
        return swap_byte64((uint64_t)x);
    else if (sizeof(T) == 4)
        return swap_byte32((uint32_t)x);
    else if (sizeof(T) == 2)
        return swap_byte16((uint16_t)x);
    else if (sizeof(T) == 1)
        return x;
    else
        panic("Can't byte-swap values larger than 64 bits");
}

template<>
static inline Twin64_t swap_byte<Twin64_t>(Twin64_t x)
{
    x.a = swap_byte(x.a);
    x.b = swap_byte(x.b);
    return x;
}

template<>
static inline Twin32_t swap_byte<Twin32_t>(Twin32_t x)
{
    x.a = swap_byte(x.a);
    x.b = swap_byte(x.b);
    return x;
}

//The conversion functions with fixed endianness on both ends don't need to
//be in a namespace
template <typename T> static inline T betole(T value) {return swap_byte(value);}
template <typename T> static inline T letobe(T value) {return swap_byte(value);}

//For conversions not involving the guest system, we can define the functions
//conditionally based on the BYTE_ORDER macro and outside of the namespaces
#if defined(_BIG_ENDIAN) || !defined(_LITTLE_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
const ByteOrder HostByteOrder = BigEndianByteOrder;
template <typename T> static inline T htole(T value) {return swap_byte(value);}
template <typename T> static inline T letoh(T value) {return swap_byte(value);}
template <typename T> static inline T htobe(T value) {return value;}
template <typename T> static inline T betoh(T value) {return value;}
#elif defined(_LITTLE_ENDIAN) || BYTE_ORDER == LITTLE_ENDIAN
const ByteOrder HostByteOrder = LittleEndianByteOrder;
template <typename T> static inline T htole(T value) {return value;}
template <typename T> static inline T letoh(T value) {return value;}
template <typename T> static inline T htobe(T value) {return swap_byte(value);}
template <typename T> static inline T betoh(T value) {return swap_byte(value);}
#else
        #error Invalid Endianess
#endif

namespace BigEndianGuest
{
    const bool ByteOrderDiffers = (HostByteOrder != BigEndianByteOrder);
    template <typename T>
    static inline T gtole(T value) {return betole(value);}
    template <typename T>
    static inline T letog(T value) {return letobe(value);}
    template <typename T>
    static inline T gtobe(T value) {return value;}
    template <typename T>
    static inline T betog(T value) {return value;}
    template <typename T>
    static inline T htog(T value) {return htobe(value);}
    template <typename T>
    static inline T gtoh(T value) {return betoh(value);}
}

namespace LittleEndianGuest
{
    const bool ByteOrderDiffers = (HostByteOrder != LittleEndianByteOrder);
    template <typename T>
    static inline T gtole(T value) {return value;}
    template <typename T>
    static inline T letog(T value) {return value;}
    template <typename T>
    static inline T gtobe(T value) {return letobe(value);}
    template <typename T>
    static inline T betog(T value) {return betole(value);}
    template <typename T>
    static inline T htog(T value) {return htole(value);}
    template <typename T>
    static inline T gtoh(T value) {return letoh(value);}
}
#endif // __SIM_BYTE_SWAP_HH__
