1 #ifndef _BURN_ENDIAN_H
2 #define _BURN_ENDIAN_H
3
4 #ifdef LSB_FIRST
5 typedef union
6 {
7 struct { UINT8 l,h,h2,h3; } b;
8 struct { UINT16 l,h; } w;
9 UINT32 d;
10 } PAIR;
11
12 #define BURN_ENDIAN_SWAP_INT8(x) x
13 #define BURN_ENDIAN_SWAP_INT16(x) x
14 #define BURN_ENDIAN_SWAP_INT32(x) x
15 #define BURN_ENDIAN_SWAP_INT64(x) x
16 #else
17
18 // Xbox 360 has byteswap 64-bit intrinsic
19 #ifndef _XBOX
20 #define NO_64BIT_BYTESWAP
21 #endif
22
23 // psl1ght uses those intrinsics too
24 #if defined(__PSL1GHT__) && !defined(__CELLOS_LV2__)
25 #define __CELLOS_LV2__
26 #endif
27
28 typedef union {
29 struct { UINT8 h3,h2,h,l; } b;
30 struct { UINT16 h,l; } w;
31 UINT32 d;
32 } PAIR;
33
34 #ifdef NO_64BIT_BYTESWAP
35 typedef union {
36 UINT64 ll;
37 struct { UINT32 l, h; } l;
38 } BYTESWAP_INT64;
39 #endif
40
41 // Libogc doesn't have intrinsics or ASM macros defined for this
42 #if defined(HW_RVL) || defined(GEKKO)
43 #define __sthbrx(base,index,value) \
44 __asm__ volatile ("sthbrx %0,%1,%2" : : "r"(value), "b%"(index), "r"(base) : "memory")
45
46 #define __stwbrx(base,index,value) \
47 __asm__ volatile ("stwbrx %0,%1,%2" : : "r"(value), "b%"(index), "r"(base) : "memory")
48 #endif
49
50 // Xbox 360
51 #if defined(_XBOX)
52 #define BURN_ENDIAN_SWAP_INT8(x) (x^1)
53 #define BURN_ENDIAN_SWAP_INT16(x) (_byteswap_ushort(x))
54 #define BURN_ENDIAN_SWAP_INT32(x) (_byteswap_ulong(x))
55 #define BURN_ENDIAN_SWAP_INT64(x) (_byteswap_uint64(x))
56 // PS3
57 #elif defined(__CELLOS_LV2__)
58 #include <ppu_intrinsics.h>
59 #include <math.h>
60 #define BURN_ENDIAN_SWAP_INT8(x) (x^1)
61 #define BURN_ENDIAN_SWAP_INT16(x) ({uint16_t tt; __sthbrx(&tt, x); tt;})
62 #define BURN_ENDIAN_SWAP_INT32(x) ({uint32_t tt; __stwbrx(&tt, x); tt;})
63 // GC/Wii/WiiU
64 #elif defined(HW_RVL)
65 #define BURN_ENDIAN_SWAP_INT8(x) (x^1)
66 #define BURN_ENDIAN_SWAP_INT16(x) ({uint16_t tt; __sthbrx(&tt, 0, x); tt;})
67 #define BURN_ENDIAN_SWAP_INT32(x) ({uint32_t tt; __stwbrx(&tt, 0, x); tt;})
68 // gcc/clang
69 #elif defined(__GNUC__)
70 #define BURN_ENDIAN_SWAP_INT8(x) (x^1)
71 #define BURN_ENDIAN_SWAP_INT16(x) (__builtin_bswap16(x))
72 #define BURN_ENDIAN_SWAP_INT32(x) (__builtin_bswap32(x))
73 // Anything else (swap16 & swap32 are kinda broken though)
74 #else
75 #define BURN_ENDIAN_SWAP_INT8(x) (x^1)
76 #define BURN_ENDIAN_SWAP_INT16(x) ((((x) << 8) & 0xff00) | (((x) >> 8) & 0x00ff))
77 #define BURN_ENDIAN_SWAP_INT32(x) ((((x) << 24) & 0xff000000) | (((x) << 8) & 0x00ff0000) | (((x) >> 8) & 0x0000ff00) | (((x) >> 24) & 0x000000ff))
78 #endif
79
80 #ifdef NO_64BIT_BYTESWAP
BURN_ENDIAN_SWAP_INT64(UINT64 x)81 static inline UINT64 BURN_ENDIAN_SWAP_INT64(UINT64 x)
82 {
83 BYTESWAP_INT64 r = {0};
84 r.l.l = BURN_ENDIAN_SWAP_INT32(x);
85 r.l.h = BURN_ENDIAN_SWAP_INT32(x >> 32);
86 return r.ll;
87 }
88 #endif
89
90 #endif
91
92 #endif
93