Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/psx/octoshock/endian.h
2 views
1
#ifndef __MDFN_ENDIAN_H
2
#define __MDFN_ENDIAN_H
3
4
#pragma warning(once : 4519)
5
static INLINE uint32 BitsExtract(const uint8* ptr, const size_t bit_offset, const size_t bit_count)
6
{
7
uint32 ret = 0;
8
9
for(size_t x = 0; x < bit_count; x++)
10
{
11
size_t co = bit_offset + x;
12
bool b = (ptr[co >> 3] >> (co & 7)) & 1;
13
14
ret |= (uint64)b << x;
15
}
16
17
return ret;
18
}
19
20
static INLINE void BitsIntract(uint8* ptr, const size_t bit_offset, const size_t bit_count, uint32 value)
21
{
22
for(size_t x = 0; x < bit_count; x++)
23
{
24
size_t co = bit_offset + x;
25
bool b = (value >> x) & 1;
26
uint8 tmp = ptr[co >> 3];
27
28
tmp &= ~(1 << (co & 7));
29
tmp |= b << (co & 7);
30
31
ptr[co >> 3] = tmp;
32
}
33
}
34
35
/*
36
Regarding safety of calling MDFN_*sb<true> on dynamically-allocated memory with new uint8[], see C++ standard 3.7.3.1(i.e. it should be
37
safe provided the offsets into the memory are aligned/multiples of the MDFN_*sb access type). malloc()'d and calloc()'d
38
memory should be safe as well.
39
40
Statically-allocated arrays/memory should be unioned with a big POD type or C++11 "alignas"'d. (May need to audit code to ensure
41
this is being done).
42
*/
43
44
void Endian_A16_Swap(void *src, uint32 nelements);
45
void Endian_A32_Swap(void *src, uint32 nelements);
46
void Endian_A64_Swap(void *src, uint32 nelements);
47
48
void Endian_A16_NE_LE(void *src, uint32 nelements);
49
void Endian_A32_NE_LE(void *src, uint32 nelements);
50
void Endian_A64_NE_LE(void *src, uint32 nelements);
51
52
void Endian_A16_NE_BE(void *src, uint32 nelements);
53
void Endian_A32_NE_BE(void *src, uint32 nelements);
54
void Endian_A64_NE_BE(void *src, uint32 nelements);
55
56
void Endian_V_NE_LE(void *src, uint32 bytesize);
57
void Endian_V_NE_BE(void *src, uint32 bytesize);
58
59
static INLINE uint16 MDFN_bswap16(uint16 v)
60
{
61
return (v << 8) | (v >> 8);
62
}
63
64
static INLINE uint32 MDFN_bswap32(uint32 v)
65
{
66
return (v << 24) | ((v & 0xFF00) << 8) | ((v >> 8) & 0xFF00) | (v >> 24);
67
}
68
69
static INLINE uint64 MDFN_bswap64(uint64 v)
70
{
71
//octoshock edit
72
//return (v << 56) | (v >> 56) | ((v & 0xFF00) << 40) | ((v >> 40) & 0xFF00) | ((uint64)MDFN_bswap32(v >> 16) << 16);
73
return (v << 56) | (v >> 56) | ((v & 0xFF00) << 40) | ((v >> 40) & 0xFF00) | ((uint64)MDFN_bswap32(((uint32)v) >> 16) << 16);
74
}
75
76
#ifdef LSB_FIRST
77
#define MDFN_ENDIANH_IS_BIGENDIAN 0
78
#else
79
#define MDFN_ENDIANH_IS_BIGENDIAN 1
80
#endif
81
82
//
83
// X endian.
84
//
85
template<int isbigendian, typename T, bool aligned>
86
static INLINE T MDFN_deXsb(const void* ptr)
87
{
88
T tmp;
89
90
memcpy(&tmp, MDFN_ASSUME_ALIGNED(ptr, (aligned ? sizeof(T) : 1)), sizeof(T));
91
92
if(isbigendian != -1 && isbigendian != MDFN_ENDIANH_IS_BIGENDIAN)
93
{
94
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Gummy penguins.");
95
96
if(sizeof(T) == 8)
97
return (T)MDFN_bswap64(tmp);
98
else if(sizeof(T) == 4)
99
return (T)MDFN_bswap32(tmp);
100
else if(sizeof(T) == 2)
101
return (T)MDFN_bswap16(tmp);
102
}
103
104
return tmp;
105
}
106
107
//
108
// Native endian.
109
//
110
template<typename T, bool aligned = false>
111
static INLINE T MDFN_densb(const void* ptr)
112
{
113
return MDFN_deXsb<-1, T, aligned>(ptr);
114
}
115
116
//
117
// Little endian.
118
//
119
template<typename T, bool aligned = false>
120
static INLINE T MDFN_delsb(const void* ptr)
121
{
122
return MDFN_deXsb<0, T, aligned>(ptr);
123
}
124
125
template<bool aligned = false>
126
static INLINE uint16 MDFN_de16lsb(const void* ptr)
127
{
128
return MDFN_delsb<uint16, aligned>(ptr);
129
}
130
131
static INLINE uint32 MDFN_de24lsb(const void* ptr)
132
{
133
const uint8* morp = (const uint8*)ptr;
134
return(morp[0]|(morp[1]<<8)|(morp[2]<<16));
135
}
136
137
template<bool aligned = false>
138
static INLINE uint32 MDFN_de32lsb(const void* ptr)
139
{
140
return MDFN_delsb<uint32, aligned>(ptr);
141
}
142
143
template<bool aligned = false>
144
static INLINE uint64 MDFN_de64lsb(const void* ptr)
145
{
146
return MDFN_delsb<uint64, aligned>(ptr);
147
}
148
149
//
150
// Big endian.
151
//
152
template<typename T, bool aligned = false>
153
static INLINE T MDFN_demsb(const void* ptr)
154
{
155
return MDFN_deXsb<1, T, aligned>(ptr);
156
}
157
158
template<bool aligned = false>
159
static INLINE uint16 MDFN_de16msb(const void* ptr)
160
{
161
return MDFN_demsb<uint16, aligned>(ptr);
162
}
163
164
static INLINE uint32 MDFN_de24msb(const void* ptr)
165
{
166
const uint8* morp = (const uint8*)ptr;
167
return((morp[2]<<0)|(morp[1]<<8)|(morp[0]<<16));
168
}
169
170
template<bool aligned = false>
171
static INLINE uint32 MDFN_de32msb(const void* ptr)
172
{
173
return MDFN_demsb<uint32, aligned>(ptr);
174
}
175
176
template<bool aligned = false>
177
static INLINE uint64 MDFN_de64msb(const void* ptr)
178
{
179
return MDFN_demsb<uint64, aligned>(ptr);
180
}
181
182
//
183
//
184
//
185
//
186
//
187
//
188
//
189
//
190
191
//
192
// X endian.
193
//
194
template<int isbigendian, typename T, bool aligned>
195
static INLINE void MDFN_enXsb(void* ptr, T value)
196
{
197
T tmp = value;
198
199
if(isbigendian != -1 && isbigendian != MDFN_ENDIANH_IS_BIGENDIAN)
200
{
201
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Gummy penguins.");
202
203
if(sizeof(T) == 8)
204
tmp = (T)MDFN_bswap64(value);
205
else if(sizeof(T) == 4)
206
tmp = (T)MDFN_bswap32(value);
207
else if(sizeof(T) == 2)
208
tmp = (T)MDFN_bswap16(value);
209
}
210
211
memcpy(MDFN_ASSUME_ALIGNED(ptr, (aligned ? sizeof(T) : 1)), &tmp, sizeof(T));
212
}
213
214
//
215
// Native endian.
216
//
217
template<typename T, bool aligned = false>
218
static INLINE void MDFN_ennsb(void* ptr, T value)
219
{
220
MDFN_enXsb<-1, T, aligned>(ptr, value);
221
}
222
223
//
224
// Little endian.
225
//
226
template<typename T, bool aligned = false>
227
static INLINE void MDFN_enlsb(void* ptr, T value)
228
{
229
MDFN_enXsb<0, T, aligned>(ptr, value);
230
}
231
232
template<bool aligned = false>
233
static INLINE void MDFN_en16lsb(void* ptr, uint16 value)
234
{
235
MDFN_enlsb<uint16, aligned>(ptr, value);
236
}
237
238
static INLINE void MDFN_en24lsb(void* ptr, uint32 value)
239
{
240
uint8* morp = (uint8*)ptr;
241
242
morp[0] = value;
243
morp[1] = value >> 8;
244
morp[2] = value >> 16;
245
}
246
247
template<bool aligned = false>
248
static INLINE void MDFN_en32lsb(void* ptr, uint32 value)
249
{
250
MDFN_enlsb<uint32, aligned>(ptr, value);
251
}
252
253
template<bool aligned = false>
254
static INLINE void MDFN_en64lsb(void* ptr, uint64 value)
255
{
256
MDFN_enlsb<uint64, aligned>(ptr, value);
257
}
258
259
260
//
261
// Big endian.
262
//
263
template<typename T, bool aligned = false>
264
static INLINE void MDFN_enmsb(void* ptr, T value)
265
{
266
MDFN_enXsb<1, T, aligned>(ptr, value);
267
}
268
269
template<bool aligned = false>
270
static INLINE void MDFN_en16msb(void* ptr, uint16 value)
271
{
272
MDFN_enmsb<uint16, aligned>(ptr, value);
273
}
274
275
static INLINE void MDFN_en24msb(void* ptr, uint32 value)
276
{
277
uint8* morp = (uint8*)ptr;
278
279
morp[0] = value;
280
morp[1] = value >> 8;
281
morp[2] = value >> 16;
282
}
283
284
template<bool aligned = false>
285
static INLINE void MDFN_en32msb(void* ptr, uint32 value)
286
{
287
MDFN_enmsb<uint32, aligned>(ptr, value);
288
}
289
290
template<bool aligned = false>
291
static INLINE void MDFN_en64msb(void* ptr, uint64 value)
292
{
293
MDFN_enmsb<uint64, aligned>(ptr, value);
294
}
295
296
#endif
297
298