gem5 v24.0.0.0
Loading...
Searching...
No Matches
byteswap.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29//The purpose of this file is to provide endainness conversion utility
30//functions. Depending on the endianness of the guest system, either
31//the LittleEndianGuest or BigEndianGuest namespace is used.
32
33#ifndef __SIM_BYTE_SWAP_HH__
34#define __SIM_BYTE_SWAP_HH__
35
36// This lets us figure out what the byte order of the host system is
37#if defined(__linux__)
38#include <endian.h>
39// If this is a linux system, lets used the optimized definitions if they exist.
40// If one doesn't exist, we pretty much get what is listed below, so it all
41// works out
42#include <byteswap.h>
43#elif defined (__sun)
44#include <sys/isa_defs.h>
45#else
46#include <machine/endian.h>
47#endif
48
49#if defined(__APPLE__)
50#include <libkern/OSByteOrder.h>
51#endif
52
53#include <type_traits>
54
55#include "base/types.hh"
56#include "enums/ByteOrder.hh"
57
58struct vring_used_elem;
59struct vring_desc;
60
61namespace gem5
62{
63
64// These functions actually perform the swapping for parameters of various bit
65// lengths.
66
67inline uint64_t
68swap_byte64(uint64_t x)
69{
70#if defined(__linux__)
71 return bswap_64(x);
72#elif defined(__APPLE__)
73 return OSSwapInt64(x);
74#else
75 return (uint64_t)((((uint64_t)(x) & 0xff) << 56) |
76 ((uint64_t)(x) & 0xff00ULL) << 40 |
77 ((uint64_t)(x) & 0xff0000ULL) << 24 |
78 ((uint64_t)(x) & 0xff000000ULL) << 8 |
79 ((uint64_t)(x) & 0xff00000000ULL) >> 8 |
80 ((uint64_t)(x) & 0xff0000000000ULL) >> 24 |
81 ((uint64_t)(x) & 0xff000000000000ULL) >> 40 |
82 ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) ;
83#endif
84}
85
86inline uint32_t
87swap_byte32(uint32_t x)
88{
89#if defined(__linux__)
90 return bswap_32(x);
91#elif defined(__APPLE__)
92 return OSSwapInt32(x);
93#else
94 return (uint32_t)(((uint32_t)(x) & 0xff) << 24 |
95 ((uint32_t)(x) & 0xff00) << 8 | ((uint32_t)(x) & 0xff0000) >> 8 |
96 ((uint32_t)(x) & 0xff000000) >> 24);
97#endif
98}
99
100inline uint16_t
101swap_byte16(uint16_t x)
102{
103#if defined(__linux__)
104 return bswap_16(x);
105#elif defined(__APPLE__)
106 return OSSwapInt16(x);
107#else
108 return (uint16_t)(((uint16_t)(x) & 0xff) << 8 |
109 ((uint16_t)(x) & 0xff00) >> 8);
110#endif
111}
112
113template <typename T>
114inline std::enable_if_t<
115 sizeof(T) == 8 && std::is_convertible_v<T, uint64_t>, T>
117{
118 return swap_byte64((uint64_t)x);
119}
120
121template <typename T>
122inline std::enable_if_t<
123 sizeof(T) == 4 && std::is_convertible_v<T, uint32_t>, T>
125{
126 return swap_byte32((uint32_t)x);
127}
128
129template <typename T>
130inline std::enable_if_t<
131 sizeof(T) == 2 && std::is_convertible_v<T, uint16_t>, T>
133{
134 return swap_byte16((uint16_t)x);
135}
136
137template <typename T>
138inline std::enable_if_t<
139 sizeof(T) == 1 && std::is_convertible_v<T, uint8_t>, T>
141{
142 return x;
143}
144
145// Make the function visible in case we need to declare a version of it for
146// other types
147template <typename T>
148std::enable_if_t<std::is_same_v<T, vring_used_elem>, T>
149swap_byte(T v);
150template <typename T>
151std::enable_if_t<std::is_same_v<T, vring_desc>, T>
152swap_byte(T v);
153
154template <typename T, size_t N>
155inline std::array<T, N>
156swap_byte(std::array<T, N> a)
157{
158 for (T &v: a)
159 v = swap_byte(v);
160 return a;
161}
162
163//The conversion functions with fixed endianness on both ends don't need to
164//be in a namespace
165template <typename T> inline T betole(T value) {return swap_byte(value);}
166template <typename T> inline T letobe(T value) {return swap_byte(value);}
167
168//For conversions not involving the guest system, we can define the functions
169//conditionally based on the BYTE_ORDER macro and outside of the namespaces
170#if (defined(_BIG_ENDIAN) || !defined(_LITTLE_ENDIAN)) && BYTE_ORDER == BIG_ENDIAN
171const ByteOrder HostByteOrder = ByteOrder::big;
172template <typename T> inline T htole(T value) {return swap_byte(value);}
173template <typename T> inline T letoh(T value) {return swap_byte(value);}
174template <typename T> inline T htobe(T value) {return value;}
175template <typename T> inline T betoh(T value) {return value;}
176#elif defined(_LITTLE_ENDIAN) || BYTE_ORDER == LITTLE_ENDIAN
177const ByteOrder HostByteOrder = ByteOrder::little;
178template <typename T> inline T htole(T value) {return value;}
179template <typename T> inline T letoh(T value) {return value;}
180template <typename T> inline T htobe(T value) {return swap_byte(value);}
181template <typename T> inline T betoh(T value) {return swap_byte(value);}
182#else
183 #error Invalid Endianess
184#endif
185
186template <typename T>
187inline T htog(T value, ByteOrder guest_byte_order)
188{
189 return guest_byte_order == ByteOrder::big ?
190 htobe(value) : htole(value);
191}
192
193template <typename T>
194inline T gtoh(T value, ByteOrder guest_byte_order)
195{
196 return guest_byte_order == ByteOrder::big ?
197 betoh(value) : letoh(value);
198}
199
200} // namespace gem5
201
202#endif // __SIM_BYTE_SWAP_HH__
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
Bitfield< 28 > v
Definition misc_types.hh:54
Bitfield< 8 > a
Definition misc_types.hh:66
Bitfield< 3 > x
Definition pagetable.hh:73
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
T letoh(T value)
Definition byteswap.hh:173
T betole(T value)
Definition byteswap.hh:165
uint32_t swap_byte32(uint32_t x)
Definition byteswap.hh:87
std::enable_if_t< std::is_same_v< T, vring_used_elem >, T > swap_byte(T v)
Definition base.hh:76
T gtoh(T value, ByteOrder guest_byte_order)
Definition byteswap.hh:194
T betoh(T value)
Definition byteswap.hh:175
T htole(T value)
Definition byteswap.hh:172
T htobe(T value)
Definition byteswap.hh:174
const ByteOrder HostByteOrder
Definition byteswap.hh:171
uint16_t swap_byte16(uint16_t x)
Definition byteswap.hh:101
T htog(T value, ByteOrder guest_byte_order)
Definition byteswap.hh:187
uint64_t swap_byte64(uint64_t x)
Definition byteswap.hh:68
T letobe(T value)
Definition byteswap.hh:166

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0