1
// Copyright (c) 2012- PPSSPP Project / Dolphin Project.
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
22
#include <sys/endian.h>
24
#if _BYTE_ORDER == _LITTLE_ENDIAN && !defined(COMMON_LITTLE_ENDIAN)
25
#define COMMON_LITTLE_ENDIAN 1
26
#elif _BYTE_ORDER == _BIG_ENDIAN && !defined(COMMON_BIG_ENDIAN)
27
#define COMMON_BIG_ENDIAN 1
31
#elif __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
33
#if __BYTE_ORDER__ && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) && !defined(COMMON_LITTLE_ENDIAN)
34
#define COMMON_LITTLE_ENDIAN 1
35
#elif __BYTE_ORDER__ && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) && !defined(COMMON_BIG_ENDIAN)
36
#define COMMON_BIG_ENDIAN 1
42
#if __LITTLE_ENDIAN__ && !defined(COMMON_LITTLE_ENDIAN)
43
#define COMMON_LITTLE_ENDIAN 1
44
#elif __BIG_ENDIAN__ && !defined(COMMON_BIG_ENDIAN)
45
#define COMMON_BIG_ENDIAN 1
49
#elif defined(_MSC_VER) && !defined(COMMON_BIG_ENDIAN) && !defined(COMMON_LITTLE_ENDIAN)
52
#define COMMON_BIG_ENDIAN 1
54
#define COMMON_LITTLE_ENDIAN 1
59
// Worst case, default to little endian.
60
#if !COMMON_BIG_ENDIAN && !COMMON_LITTLE_ENDIAN
61
#define COMMON_LITTLE_ENDIAN 1
66
inline unsigned long long bswap64(unsigned long long x) { return _byteswap_uint64(x); }
67
inline unsigned int bswap32(unsigned int x) { return _byteswap_ulong(x); }
68
inline unsigned short bswap16(unsigned short x) { return _byteswap_ushort(x); }
70
inline unsigned long long bswap64(unsigned long long x) { return __loaddoublewordbytereverse(0, &x); }
71
inline unsigned int bswap32(unsigned int x) { return __loadwordbytereverse(0, &x); }
72
inline unsigned short bswap16(unsigned short x) { return __loadshortbytereverse(0, &x); }
74
#elif defined(__DragonFly__) || defined(__FreeBSD__) || \
75
defined(__NetBSD__) || defined(__OpenBSD__)
76
#include <sys/endian.h>
78
#define bswap16 swap16
79
#define bswap32 swap32
80
#define bswap64 swap64
85
inline unsigned short bswap16(unsigned short x) { return (x << 8) | (x >> 8); }
86
inline unsigned int bswap32(unsigned int x) { return (x >> 24) | ((x & 0xFF0000) >> 8) | ((x & 0xFF00) << 8) | (x << 24); }
87
inline unsigned long long bswap64(unsigned long long x) { return ((unsigned long long)bswap32(x) << 32) | bswap32(x >> 32); }
90
inline float bswapf(float f) {
97
dat2.u32 = bswap32(dat1.u32);
102
inline double bswapd(double f) {
105
unsigned long long u64;
109
dat2.u64 = bswap64(dat1.u64);
114
template <typename T, typename F>
115
struct swap_struct_t {
116
typedef swap_struct_t<T, F> swapped_t;
125
T const swap() const {
128
swap_struct_t() : value((T)0) {}
129
swap_struct_t(const T &v): value(swap(v)) {}
131
template <typename S>
132
swapped_t& operator=(const S &source) {
133
value = swap((T)source);
137
operator unsigned long() const { return (unsigned long)swap(); }
138
operator long() const { return (long)swap(); }
139
operator s8() const { return (s8)swap(); }
140
operator u8() const { return (u8)swap(); }
141
operator s16() const { return (s16)swap(); }
142
operator u16() const { return (u16)swap(); }
143
operator s32() const { return (s32)swap(); }
144
operator u32() const { return (u32)swap(); }
145
operator s64() const { return (s64)swap(); }
146
operator u64() const { return (u64)swap(); }
147
operator float() const { return (float)swap(); }
148
operator double() const { return (double)swap(); }
151
swapped_t operator +() const {
155
swapped_t operator -() const {
160
swapped_t operator/(const swapped_t &i) const {
161
return swap() / i.swap();
163
template <typename S>
164
swapped_t operator/(const S &i) const {
169
swapped_t operator*(const swapped_t &i) const {
170
return swap() * i.swap();
172
template <typename S>
173
swapped_t operator*(const S &i) const {
178
swapped_t operator+(const swapped_t &i) const {
179
return swap() + i.swap();
181
template <typename S>
182
swapped_t operator+(const S &i) const {
183
return swap() + (T)i;
186
swapped_t operator-(const swapped_t &i) const {
187
return swap() - i.swap();
189
template <typename S>
190
swapped_t operator-(const S &i) const {
191
return swap() - (T)i;
195
swapped_t& operator+=(const swapped_t &i) {
196
value = swap(swap() + i.swap());
199
template <typename S>
200
swapped_t& operator+=(const S &i) {
201
value = swap(swap() + (T)i);
205
swapped_t& operator-=(const swapped_t &i) {
206
value = swap(swap() - i.swap());
209
template <typename S>
210
swapped_t& operator-=(const S &i) {
211
value = swap(swap() - (T)i);
216
swapped_t& operator++() {
217
value = swap(swap()+1);
221
swapped_t& operator--() {
222
value = swap(swap()-1);
227
swapped_t operator++(int) {
228
swapped_t old = *this;
229
value = swap(swap()+1);
233
swapped_t operator--(int) {
234
swapped_t old = *this;
235
value = swap(swap()-1);
240
bool operator==(const swapped_t &i) const {
241
return swap() == i.swap();
243
template <typename S>
244
bool operator==(const S &i) const {
249
bool operator!=(const swapped_t &i) const {
250
return swap() != i.swap();
252
template <typename S>
253
bool operator!=(const S &i) const {
258
bool operator>(const swapped_t &i) const {
259
return swap() > i.swap();
261
template <typename S>
262
bool operator>(const S &i) const {
267
bool operator<(const swapped_t &i) const {
268
return swap() < i.swap();
270
template <typename S>
271
bool operator<(const S &i) const {
276
bool operator>=(const swapped_t &i) const {
277
return swap() >= i.swap();
279
template <typename S>
280
bool operator>=(const S &i) const {
285
bool operator<=(const swapped_t &i) const {
286
return swap() <= i.swap();
288
template <typename S>
289
bool operator<=(const S &i) const {
294
swapped_t operator !() const {
298
bool operator ||(const swapped_t & b) const {
299
return swap() || b.swap();
301
template <typename S>
302
bool operator ||(const S & b) const {
307
swapped_t operator ~() const {
311
swapped_t operator &(const swapped_t &b) const {
312
return swap() & b.swap();
314
template <typename S>
315
swapped_t operator &(const S &b) const {
318
swapped_t& operator &=(const swapped_t &b) {
319
value = swap(swap() & b.swap());
322
template <typename S>
323
swapped_t& operator &=(const S b) {
324
value = swap(swap() & b);
328
swapped_t operator |(const swapped_t &b) const {
329
return swap() | b.swap();
331
template <typename S>
332
swapped_t operator |(const S &b) const {
335
swapped_t& operator |=(const swapped_t &b) {
336
value = swap(swap() | b.swap());
339
template <typename S>
340
swapped_t& operator |=(const S &b) {
341
value = swap(swap() | b);
345
swapped_t operator ^(const swapped_t &b) const {
346
return swap() ^ b.swap();
348
template <typename S>
349
swapped_t operator ^(const S &b) const {
352
swapped_t& operator ^=(const swapped_t &b) {
353
value = swap(swap() ^ b.swap());
356
template <typename S>
357
swapped_t& operator ^=(const S &b) {
358
value = swap(swap() ^ b);
362
template <typename S>
363
swapped_t operator <<(const S &b) const {
366
template <typename S>
367
swapped_t& operator <<=(const S &b) const {
368
value = swap(swap() << b);
372
template <typename S>
373
swapped_t operator >>(const S &b) const {
376
template <typename S>
377
swapped_t& operator >>=(const S &b) const {
378
value = swap(swap() >> b);
387
template <typename S, typename T2, typename F2>
388
friend S operator+(const S &p, const swapped_t& v);
390
template <typename S, typename T2, typename F2>
391
friend S operator-(const S &p, const swapped_t& v);
393
template <typename S, typename T2, typename F2>
394
friend S operator/(const S &p, const swapped_t& v);
396
template <typename S, typename T2, typename F2>
397
friend S operator*(const S &p, const swapped_t& v);
399
template <typename S, typename T2, typename F2>
400
friend S operator%(const S &p, const swapped_t& v);
402
// Arithmetics + assignements
403
template <typename S, typename T2, typename F2>
404
friend S operator+=(const S &p, const swapped_t& v);
406
template <typename S, typename T2, typename F2>
407
friend S operator-=(const S &p, const swapped_t& v);
410
template <typename S, typename T2, typename F2>
411
friend S operator&(const S &p, const swapped_t& v);
414
template <typename S, typename T2, typename F2>
415
friend bool operator<(const S &p, const swapped_t& v);
417
template <typename S, typename T2, typename F2>
418
friend bool operator>(const S &p, const swapped_t& v);
420
template <typename S, typename T2, typename F2>
421
friend bool operator<=(const S &p, const swapped_t& v);
423
template <typename S, typename T2, typename F2>
424
friend bool operator>=(const S &p, const swapped_t& v);
426
template <typename S, typename T2, typename F2>
427
friend bool operator!=(const S &p, const swapped_t& v);
429
template <typename S, typename T2, typename F2>
430
friend bool operator==(const S &p, const swapped_t& v);
435
template <typename S, typename T, typename F>
436
S operator+(const S &i, const swap_struct_t<T, F>& v) {
440
template <typename S, typename T, typename F>
441
S operator-(const S &i, const swap_struct_t<T, F>& v) {
445
template <typename S, typename T, typename F>
446
S operator/(const S &i, const swap_struct_t<T, F>& v) {
450
template <typename S, typename T, typename F>
451
S operator*(const S &i, const swap_struct_t<T, F>& v) {
455
template <typename S, typename T, typename F>
456
S operator%(const S &i, const swap_struct_t<T, F>& v) {
460
// Arithmetics + assignements
461
template <typename S, typename T, typename F>
462
S &operator+=(S &i, const swap_struct_t<T, F>& v) {
467
template <typename S, typename T, typename F>
468
S &operator-=(S &i, const swap_struct_t<T, F>& v) {
474
template <typename S, typename T, typename F>
475
S operator&(const S &i, const swap_struct_t<T, F>& v) {
479
template <typename S, typename T, typename F>
480
S operator&(const swap_struct_t<T, F>& v, const S &i) {
481
return (S)(v.swap() & i);
486
template <typename S, typename T, typename F>
487
bool operator<(const S &p, const swap_struct_t<T, F>& v) {
490
template <typename S, typename T, typename F>
491
bool operator>(const S &p, const swap_struct_t<T, F>& v) {
494
template <typename S, typename T, typename F>
495
bool operator<=(const S &p, const swap_struct_t<T, F>& v) {
496
return p <= v.swap();
498
template <typename S, typename T, typename F>
499
bool operator>=(const S &p, const swap_struct_t<T, F>& v) {
500
return p >= v.swap();
502
template <typename S, typename T, typename F>
503
bool operator!=(const S &p, const swap_struct_t<T, F>& v) {
504
return p != v.swap();
506
template <typename S, typename T, typename F>
507
bool operator==(const S &p, const swap_struct_t<T, F>& v) {
508
return p == v.swap();
511
template <typename T>
514
return (T)bswap64(*(u64 *)&x);
518
template <typename T>
521
return (T)bswap32(*(u32 *)&x);
525
template <typename T>
528
return (T)bswap16(*(u16 *)&x);
532
template <typename T>
533
struct swap_float_t {
535
return (T)bswapf(*(float *)&x);
539
template <typename T>
540
struct swap_double_t {
542
return (T)bswapd(*(double *)&x);
546
#if COMMON_LITTLE_ENDIAN
555
typedef float float_le;
556
typedef double double_le;
558
typedef swap_struct_t<u64, swap_64_t<u64>> u64_be;
559
typedef swap_struct_t<s64, swap_64_t<s64>> s64_be;
561
typedef swap_struct_t<u32, swap_32_t<u32>> u32_be;
562
typedef swap_struct_t<s32, swap_32_t<s32>> s32_be;
564
typedef swap_struct_t<u16, swap_16_t<u16>> u16_be;
565
typedef swap_struct_t<s16, swap_16_t<s16>> s16_be;
567
typedef swap_struct_t<float, swap_float_t<float> > float_be;
568
typedef swap_struct_t<double, swap_double_t<double> > double_be;
571
typedef swap_struct_t<u64, swap_64_t<u64>> u64_le;
572
typedef swap_struct_t<s64, swap_64_t<s64>> s64_le;
574
typedef swap_struct_t<u32, swap_32_t<u32>> u32_le;
575
typedef swap_struct_t<s32, swap_32_t<s32>> s32_le;
577
typedef swap_struct_t<u16, swap_16_t<u16>> u16_le;
578
typedef swap_struct_t<s16, swap_16_t<s16>> s16_le;
580
typedef swap_struct_t<float, swap_float_t<float> > float_le;
581
typedef swap_struct_t<double, swap_double_t<double> > double_le;
591
typedef float float_be;
592
typedef double double_be;