byteman  1.3 (Build #225)
Bitstream relocation and manipulation tool
Endianness.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2022 Kristiyan Manev (University of Manchester)
3  *
4  * Licensed under the Apache License, Version 2.0(the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *****************************************************************************/
16 
17 #ifndef ENDIANESS_H
18 #define ENDIANESS_H
19 
20 #include<cstdint> //uint
21 #include<string>
22 
23 #if __has_include(<sys/param.h>)
24 #include<sys/param.h>
25 #endif
26 
27 
28 
29 #if (defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN) || (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__)
30  #define IS_LITTLE_ENDIAN() 0
31 #elif defined(_WIN32) || (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__)
32  #define IS_LITTLE_ENDIAN() 1
33 #else
34  #error Could not determine machine endianness in the preprocessor!
35  inline int IS_LITTLE_ENDIAN()
36  {
37  union {
38  unsigned int v;
39  unsigned char b;
40  } u;
41  u.v = 1;
42  return u.b;
43  }
44 #endif
45 
46 enum class Endianness
47 {
48  BE,
49  LE,
50  BE_BS,
51  LE_BS,
53 };
54 
55 namespace Endian {
56  inline std::string to_string(Endianness e)
57  {
58  if(Endianness::NATIVE == e)
59  return "Native";
60  if(Endianness::BE == e)
61  return "Big Endian";
62  if(Endianness::LE == e)
63  return "Little Endian";
64  if(Endianness::BE_BS == e)
65  return "Big Endian with BitSwap";
66  if(Endianness::LE_BS == e)
67  return "Little Endian with BitSwap";
68  return "null"; //should not be reached.
69  }
70  inline Endianness toggleEndianness(Endianness e, bool toggle = true)
71  {
72  if(!toggle)
73  return e;
74  if(Endianness::BE == e)
75  return Endianness::LE;
76  if(Endianness::LE == e)
77  return Endianness::BE;
78  if(Endianness::BE_BS == e)
79  return Endianness::LE_BS;
80  if(Endianness::LE_BS == e)
81  return Endianness::BE_BS;
82  return Endianness::NATIVE; //should not be reached.
83  }
84  inline Endianness toggleEndianBitSwap(Endianness e, bool toggle = true)
85  {
86  if(!toggle)
87  return e;
88  if(Endianness::BE == e)
89  return Endianness::BE_BS;
90  if(Endianness::LE == e)
91  return Endianness::LE_BS;
92  if(Endianness::BE_BS == e)
93  return Endianness::BE;
94  if(Endianness::LE_BS == e)
95  return Endianness::LE;
96  return Endianness::NATIVE; //should not be reached.
97  }
98  inline bool isBitSwap(Endianness e)
99  {
100  return (Endianness::BE_BS == e || Endianness::LE_BS == e);
101  }
102  inline bool isLE(Endianness e)
103  {
104  return (Endianness::LE == e || Endianness::LE_BS == e);
105  }
106  inline bool isBE(Endianness e)
107  {
108  return (Endianness::BE == e || Endianness::BE_BS == e);
109  }
110 /**************************************************************************/
118  {
119  Endianness accumulatedEndiannessDiff = Endianness::NATIVE;
120 
121  accumulatedEndiannessDiff = toggleEndianBitSwap(accumulatedEndiannessDiff, isBitSwap(e1));
122  accumulatedEndiannessDiff = toggleEndianBitSwap(accumulatedEndiannessDiff, isBitSwap(e2));
123 
124  accumulatedEndiannessDiff = toggleEndianness(accumulatedEndiannessDiff, isLE(e1));
125  accumulatedEndiannessDiff = toggleEndianness(accumulatedEndiannessDiff, isLE(e2));
126 
127  return accumulatedEndiannessDiff;
128  }
129 
130  inline uint16_t swapbytes16(uint16_t x)
131  {
132  return (uint16_t)(((uint16_t)(x) & 0xFFU) << 8 | ((uint16_t)(x) & 0xFF00U) >> 8);
133  }
134  inline uint32_t swapbytes32(uint32_t x)
135  {
136  return (uint32_t)(((uint32_t)(x) & 0xFF) << 24 | ((uint32_t)(x) & 0xFF00) << 8 | ((uint32_t)(x) & 0xFF0000) >> 8 | ((uint32_t)(x) & 0xFF000000) >> 24);
137  }
138  inline uint64_t swapbytes64(uint64_t x)
139  {
140  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);
141  }
142 
143 
144  inline uint8_t NativeToBigEndian8 (uint8_t x)
145  {
146  return ((uint8_t)(x));
147  }
148  inline uint16_t NativeToBigEndian16(uint16_t x)
149  {
150  return (Endianness::NATIVE == Endianness::BE)?((uint16_t)(x)):swapbytes16(x);
151  }
152  inline uint32_t NativeToBigEndian32(uint32_t x)
153  {
154  return (Endianness::NATIVE == Endianness::BE)?((uint32_t)(x)):swapbytes32(x);
155  }
156  inline uint64_t NativeToBigEndian64(uint64_t x)
157  {
158  return (Endianness::NATIVE == Endianness::BE)?((uint64_t)(x)):swapbytes64(x);
159  }
160 
161  inline uint8_t NativeToLittleEndian8 (uint8_t x)
162  {
163  return ((uint8_t)(x));
164  }
165  inline uint16_t NativeToLittleEndian16(uint16_t x)
166  {
167  return (Endianness::NATIVE == Endianness::LE)?((uint16_t)(x)):swapbytes16(x);
168  }
169  inline uint32_t NativeToLittleEndian32(uint32_t x)
170  {
171  return (Endianness::NATIVE == Endianness::LE)?((uint32_t)(x)):swapbytes32(x);
172  }
173  inline uint64_t NativeToLittleEndian64(uint64_t x)
174  {
175  return (Endianness::NATIVE == Endianness::LE)?((uint64_t)(x)):swapbytes64(x);
176  }
177 
178  inline uint8_t BigEndianToNative8(uint8_t x)
179  {
180  return ((uint8_t)(x));
181  }
182  inline uint16_t BigEndianToNative16(uint16_t x)
183  {
184  return NativeToBigEndian16(x);
185  }
186  inline uint32_t BigEndianToNative32(uint32_t x)
187  {
188  return NativeToBigEndian32(x);
189  }
190  inline uint64_t BigEndianToNative64(uint64_t x)
191  {
192  return NativeToBigEndian64(x);
193  }
194  inline uint8_t LittleEndianToNative8(uint8_t x)
195  {
196  return ((uint8_t)(x));
197  }
198  inline uint16_t LittleEndianToNative16(uint16_t x)
199  {
200  return NativeToLittleEndian16(x);
201  }
202  inline uint32_t LittleEndianToNative32(uint32_t x)
203  {
204  return NativeToLittleEndian32(x);
205  }
206  inline uint64_t LittleEndianToNative64(uint64_t x)
207  {
208  return NativeToLittleEndian64(x);
209  }
210 
211  //BitSwaps: swap bit order within the bytes
212  inline uint8_t BitSwap8(uint8_t x)
213  {
214  return (((x & 0x80)>>7) | ((x & 0x40)>>5) | ((x & 0x20)>>3) | ((x & 0x10)>>1) | ((x & 0x08) << 1) | ((x & 0x04) << 3) | ((x & 0x02) << 5) | ((x & 0x01) << 7));
215  }
216  inline uint16_t BitSwap16(uint16_t x)
217  {
218  return (((x & 0x8080)>>7) | ((x & 0x4040)>>5) | ((x & 0x2020)>>3) | ((x & 0x1010)>>1) | ((x & 0x0808) << 1) | ((x & 0x0404) << 3) | ((x & 0x0202) << 5) | ((x & 0x0101) << 7));
219  }
220  inline uint32_t BitSwap32(uint32_t x)
221  {
222  return (((x & 0x80808080)>>7) | ((x & 0x40404040)>>5) | ((x & 0x20202020)>>3) | ((x & 0x10101010)>>1) | ((x & 0x08080808) << 1) | ((x & 0x04040404) << 3) | ((x & 0x02020202) << 5) | ((x & 0x01010101) << 7));
223  }
224  inline uint64_t BitSwap64(uint64_t x)
225  {
226  return (((x & 0x8080808080808080)>>7) | ((x & 0x4040404040404040)>>5) | ((x & 0x2020202020202020)>>3) | ((x & 0x1010101010101010)>>1) | ((x & 0x0808080808080808) << 1) | ((x & 0x0404040404040404) << 3) | ((x & 0x0202020202020202) << 5) | ((x & 0x0101010101010101) << 7));
227  }
228 
229  inline uint8_t NativeToAnyEndianness8(uint8_t x, Endianness e)
230  {
231  return ((uint8_t)(x));
232  }
233  inline uint16_t NativeToAnyEndianness16(uint16_t x, Endianness e)
234  {
235  if(Endianness::BE == e)
236  return NativeToBigEndian16(x);
237  if(Endianness::LE == e)
238  return NativeToLittleEndian16(x);
239  if(Endianness::BE_BS == e)
240  return BitSwap16(NativeToBigEndian16(x));
241  if(Endianness::LE_BS == e)
243  //Native then
244  return ((uint16_t)(x));
245  }
246  inline uint32_t NativeToAnyEndianness32(uint32_t x, Endianness e)
247  {
248  if(Endianness::BE == e)
249  return NativeToBigEndian32(x);
250  if(Endianness::LE == e)
251  return NativeToLittleEndian32(x);
252  if(Endianness::BE_BS == e)
253  return BitSwap32(NativeToBigEndian32(x));
254  if(Endianness::LE_BS == e)
256  //Native then
257  return ((uint32_t)(x));
258  }
259  inline uint64_t NativeToAnyEndianness64(uint64_t x, Endianness e)
260  {
261  if(Endianness::BE == e)
262  return NativeToBigEndian64(x);
263  if(Endianness::LE == e)
264  return NativeToLittleEndian64(x);
265  if(Endianness::BE_BS == e)
266  return BitSwap64(NativeToBigEndian64(x));
267  if(Endianness::LE_BS == e)
269  //Native then
270  return ((uint64_t)(x));
271  }
272 }
273 #endif //ENDIANESS_H
Endianness
< Endianness in byteman is represented not only by big/little endian, but also by potential bit swapp...
Definition: Endianness.h:47
@ BE_BS
Big endian with bit swaps inside each byte.
@ LE_BS
Little endian with bit swaps inside each byte.
@ LE
Little endian ("LE" instead of full-er name, so it does not conflict with linux's reserved endianess ...
@ BE
Big endian ("BE" instead of full-er name, so it does not conflict with linux's reserved endianess wor...
@ NATIVE
System native will always be the fastest endianess to process.
int IS_LITTLE_ENDIAN()
Definition: Endianness.h:35
bool isBitSwap(Endianness e)
Definition: Endianness.h:98
uint64_t NativeToBigEndian64(uint64_t x)
Definition: Endianness.h:156
bool isBE(Endianness e)
Definition: Endianness.h:106
uint8_t BigEndianToNative8(uint8_t x)
Definition: Endianness.h:178
bool isLE(Endianness e)
Definition: Endianness.h:102
uint16_t BitSwap16(uint16_t x)
Definition: Endianness.h:216
uint8_t BitSwap8(uint8_t x)
Definition: Endianness.h:212
uint16_t swapbytes16(uint16_t x)
Definition: Endianness.h:130
uint8_t LittleEndianToNative8(uint8_t x)
Definition: Endianness.h:194
uint16_t NativeToLittleEndian16(uint16_t x)
Definition: Endianness.h:165
Endianness toggleEndianBitSwap(Endianness e, bool toggle=true)
Definition: Endianness.h:84
uint32_t NativeToLittleEndian32(uint32_t x)
Definition: Endianness.h:169
uint64_t BitSwap64(uint64_t x)
Definition: Endianness.h:224
uint32_t BigEndianToNative32(uint32_t x)
Definition: Endianness.h:186
uint64_t BigEndianToNative64(uint64_t x)
Definition: Endianness.h:190
uint32_t NativeToAnyEndianness32(uint32_t x, Endianness e)
Definition: Endianness.h:246
uint64_t NativeToLittleEndian64(uint64_t x)
Definition: Endianness.h:173
uint32_t swapbytes32(uint32_t x)
Definition: Endianness.h:134
uint32_t NativeToBigEndian32(uint32_t x)
Definition: Endianness.h:152
Endianness toggleEndianness(Endianness e, bool toggle=true)
Definition: Endianness.h:70
uint64_t NativeToAnyEndianness64(uint64_t x, Endianness e)
Definition: Endianness.h:259
std::string to_string(Endianness e)
Definition: Endianness.h:56
uint16_t NativeToBigEndian16(uint16_t x)
Definition: Endianness.h:148
uint8_t NativeToAnyEndianness8(uint8_t x, Endianness e)
Definition: Endianness.h:229
uint64_t LittleEndianToNative64(uint64_t x)
Definition: Endianness.h:206
uint32_t LittleEndianToNative32(uint32_t x)
Definition: Endianness.h:202
uint16_t NativeToAnyEndianness16(uint16_t x, Endianness e)
Definition: Endianness.h:233
uint32_t BitSwap32(uint32_t x)
Definition: Endianness.h:220
uint64_t swapbytes64(uint64_t x)
Definition: Endianness.h:138
Endianness diff(Endianness e1, Endianness e2)
Definition: Endianness.h:117
uint16_t LittleEndianToNative16(uint16_t x)
Definition: Endianness.h:198
uint8_t NativeToLittleEndian8(uint8_t x)
Definition: Endianness.h:161
uint8_t NativeToBigEndian8(uint8_t x)
Definition: Endianness.h:144
uint16_t BigEndianToNative16(uint16_t x)
Definition: Endianness.h:182