byteswap.hh

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 202 行

HH
202
字号
/* * Copyright (c) 2004 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Gabe M. Black *          Ali G. Saidi *          Nathan L. 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>#endifenum ByteOrder {BigEndianByteOrder, LittleEndianByteOrder};//These functions actually perform the swapping for parameters//of various bit lengthsstatic inline uint64_tswap_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_tswap_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_tswap_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 namespacetemplate <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_ENDIANconst 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_ENDIANconst 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#endifnamespace 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__

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?