1 /* Copyright (C) 2020 Wildfire Games.
3 * Permission is hereby granted, free of charge, to any person obtaining
4 * a copy of this software and associated documentation files (the
5 * "Software"), to deal in the Software without restriction, including
6 * without limitation the rights to use, copy, modify, merge, publish,
7 * distribute, sublicense, and/or sell copies of the Software, and to
8 * permit persons to whom the Software is furnished to do so, subject to
9 * the following conditions:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * byte order (endianness) support routines.
27 #include "precompiled.h"
28 #include "lib/byte_order.h"
35 u16
swap16(const u16 x
)
37 return (u16
)(((x
& 0xff) << 8) | (x
>> 8));
42 u32
swap32(const u32 x
)
46 ((x
<< 8) & 0x00ff0000) |
47 ((x
>> 8) & 0x0000ff00);
52 u64
swap64(const u64 x
)
54 const u32 lo
= (u32
)(x
& 0xFFFFFFFF);
55 const u32 hi
= (u32
)(x
>> 32);
58 // careful: must shift var of type u64, not u32
65 //-----------------------------------------------------------------------------
68 u16
read_le16(const void* p
)
71 memcpy(&n
, p
, sizeof(n
));
75 u32
read_le32(const void* p
)
78 memcpy(&n
, p
, sizeof(n
));
82 u64
read_le64(const void* p
)
85 memcpy(&n
, p
, sizeof(n
));
90 u16
read_be16(const void* p
)
93 memcpy(&n
, p
, sizeof(n
));
97 u32
read_be32(const void* p
)
100 memcpy(&n
, p
, sizeof(n
));
104 u64
read_be64(const void* p
)
107 memcpy(&n
, p
, sizeof(n
));
112 void write_le16(void* p
, u16 x
)
115 memcpy(p
, &n
, sizeof(n
));
118 void write_le32(void* p
, u32 x
)
121 memcpy(p
, &n
, sizeof(n
));
124 void write_le64(void* p
, u64 x
)
127 memcpy(p
, &n
, sizeof(n
));
131 void write_be16(void* p
, u16 x
)
134 memcpy(p
, &n
, sizeof(n
));
137 void write_be32(void* p
, u32 x
)
140 memcpy(p
, &n
, sizeof(n
));
143 void write_be64(void* p
, u64 x
)
146 memcpy(p
, &n
, sizeof(n
));
150 u64
movzx_le64(const u8
* p
, size_t size_bytes
)
153 for(size_t i
= 0; i
< std::min(size_bytes
, (size_t)8u); i
++)
154 number
|= ((u64
)p
[i
]) << (i
*8);
159 u64
movzx_be64(const u8
* p
, size_t size_bytes
)
162 for(size_t i
= 0; i
< std::min(size_bytes
, (size_t)8u); i
++)
172 static inline i64
SignExtend(u64 bits
, size_t size_bytes
)
174 // no point in sign-extending if >= 8 bytes were requested
177 const u64 sign_bit
= Bit
<u64
>((size_bytes
*8)-1);
179 // number would be negative in the smaller type,
180 // so sign-extend, i.e. set all more significant bits.
183 const u64 valid_bit_mask
= (sign_bit
+sign_bit
)-1;
184 bits
|= ~valid_bit_mask
;
188 const i64 number
= static_cast<i64
>(bits
);
192 i64
movsx_le64(const u8
* p
, size_t size_bytes
)
194 const u64 number
= movzx_le64(p
, size_bytes
);
195 return SignExtend(number
, size_bytes
);
198 i64
movsx_be64(const u8
* p
, size_t size_bytes
)
200 const u64 number
= movzx_be64(p
, size_bytes
);
201 return SignExtend(number
, size_bytes
);