LMMS
Loading...
Searching...
No Matches
blargg_endian.h
Go to the documentation of this file.
1// CPU Byte Order Utilities
2
3#ifndef BLARGG_ENDIAN
4#define BLARGG_ENDIAN
5
6#include "blargg_common.h"
7
8// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
9#if defined (__i386__) || defined (__x86_64__) || defined (_M_IX86) || defined (_M_X64)
10 #define BLARGG_CPU_X86 1
11 #define BLARGG_CPU_CISC 1
12#endif
13
14#if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) || \
15 defined (__POWERPC__) || defined (__powerc)
16 #define BLARGG_CPU_POWERPC 1
17 #define BLARGG_CPU_RISC 1
18#endif
19
20// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
21// one may be #defined to 1. Only needed if something actually depends on byte order.
22#if !defined (BLARGG_BIG_ENDIAN) && !defined (BLARGG_LITTLE_ENDIAN)
23#ifdef __GLIBC__
24 // GCC handles this for us
25 #include <endian.h>
26 #if __BYTE_ORDER == __LITTLE_ENDIAN
27 #define BLARGG_LITTLE_ENDIAN 1
28 #elif __BYTE_ORDER == __BIG_ENDIAN
29 #define BLARGG_BIG_ENDIAN 1
30 #endif
31#else
32
33#if defined (LSB_FIRST) || defined (__LITTLE_ENDIAN__) || BLARGG_CPU_X86 || \
34 (defined (LITTLE_ENDIAN) && LITTLE_ENDIAN+0 != 1234)
35 #define BLARGG_LITTLE_ENDIAN 1
36#endif
37
38#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \
39 defined (__sparc__) || BLARGG_CPU_POWERPC || \
40 (defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321)
41 #define BLARGG_BIG_ENDIAN 1
42#elif !defined (__mips__)
43 // No endian specified; assume little-endian, since it's most common
44 #define BLARGG_LITTLE_ENDIAN 1
45#endif
46#endif
47#endif
48
49#if BLARGG_LITTLE_ENDIAN && BLARGG_BIG_ENDIAN
50 #undef BLARGG_LITTLE_ENDIAN
51 #undef BLARGG_BIG_ENDIAN
52#endif
53
55{
56 #ifndef NDEBUG
57 #if BLARGG_BIG_ENDIAN
58 volatile int i = 1;
59 assert( *(volatile char*) &i == 0 );
60 #elif BLARGG_LITTLE_ENDIAN
61 volatile int i = 1;
62 assert( *(volatile char*) &i != 0 );
63 #endif
64 #endif
65}
66
67inline unsigned get_le16( void const* p )
68{
69 return (unsigned) ((unsigned char const*) p) [1] << 8 |
70 (unsigned) ((unsigned char const*) p) [0];
71}
72
73inline unsigned get_be16( void const* p )
74{
75 return (unsigned) ((unsigned char const*) p) [0] << 8 |
76 (unsigned) ((unsigned char const*) p) [1];
77}
78
79inline blargg_ulong get_le32( void const* p )
80{
81 return (blargg_ulong) ((unsigned char const*) p) [3] << 24 |
82 (blargg_ulong) ((unsigned char const*) p) [2] << 16 |
83 (blargg_ulong) ((unsigned char const*) p) [1] << 8 |
84 (blargg_ulong) ((unsigned char const*) p) [0];
85}
86
87inline blargg_ulong get_be32( void const* p )
88{
89 return (blargg_ulong) ((unsigned char const*) p) [0] << 24 |
90 (blargg_ulong) ((unsigned char const*) p) [1] << 16 |
91 (blargg_ulong) ((unsigned char const*) p) [2] << 8 |
92 (blargg_ulong) ((unsigned char const*) p) [3];
93}
94
95inline void set_le16( void* p, unsigned n )
96{
97 ((unsigned char*) p) [1] = (unsigned char) (n >> 8);
98 ((unsigned char*) p) [0] = (unsigned char) n;
99}
100
101inline void set_be16( void* p, unsigned n )
102{
103 ((unsigned char*) p) [0] = (unsigned char) (n >> 8);
104 ((unsigned char*) p) [1] = (unsigned char) n;
105}
106
107inline void set_le32( void* p, blargg_ulong n )
108{
109 ((unsigned char*) p) [0] = (unsigned char) n;
110 ((unsigned char*) p) [1] = (unsigned char) (n >> 8);
111 ((unsigned char*) p) [2] = (unsigned char) (n >> 16);
112 ((unsigned char*) p) [3] = (unsigned char) (n >> 24);
113}
114
115inline void set_be32( void* p, blargg_ulong n )
116{
117 ((unsigned char*) p) [3] = (unsigned char) n;
118 ((unsigned char*) p) [2] = (unsigned char) (n >> 8);
119 ((unsigned char*) p) [1] = (unsigned char) (n >> 16);
120 ((unsigned char*) p) [0] = (unsigned char) (n >> 24);
121}
122
123#if BLARGG_NONPORTABLE
124 // Optimized implementation if byte order is known
125 #if BLARGG_LITTLE_ENDIAN
126 #define GET_LE16( addr ) (*(uint16_t*) (addr))
127 #define GET_LE32( addr ) (*(uint32_t*) (addr))
128 #define SET_LE16( addr, data ) (void) (*(uint16_t*) (addr) = (data))
129 #define SET_LE32( addr, data ) (void) (*(uint32_t*) (addr) = (data))
130 #elif BLARGG_BIG_ENDIAN
131 #define GET_BE16( addr ) (*(uint16_t*) (addr))
132 #define GET_BE32( addr ) (*(uint32_t*) (addr))
133 #define SET_BE16( addr, data ) (void) (*(uint16_t*) (addr) = (data))
134 #define SET_BE32( addr, data ) (void) (*(uint32_t*) (addr) = (data))
135
136 #if BLARGG_CPU_POWERPC
137 // PowerPC has special byte-reversed instructions
138 #if defined (__MWERKS__)
139 #define GET_LE16( addr ) (__lhbrx( addr, 0 ))
140 #define GET_LE32( addr ) (__lwbrx( addr, 0 ))
141 #define SET_LE16( addr, in ) (__sthbrx( in, addr, 0 ))
142 #define SET_LE32( addr, in ) (__stwbrx( in, addr, 0 ))
143 #elif defined (__GNUC__)
144 #define GET_LE16( addr ) ({unsigned short ppc_lhbrx_; __asm__ volatile( "lhbrx %0,0,%1" : "=r" (ppc_lhbrx_) : "r" (addr) : "memory" ); ppc_lhbrx_;})
145 #define GET_LE32( addr ) ({unsigned short ppc_lwbrx_; __asm__ volatile( "lwbrx %0,0,%1" : "=r" (ppc_lwbrx_) : "r" (addr) : "memory" ); ppc_lwbrx_;})
146 #define SET_LE16( addr, in ) ({__asm__ volatile( "sthbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
147 #define SET_LE32( addr, in ) ({__asm__ volatile( "stwbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
148 #endif
149 #endif
150 #endif
151#endif
152
153#ifndef GET_LE16
154 #define GET_LE16( addr ) get_le16( addr )
155 #define SET_LE16( addr, data ) set_le16( addr, data )
156#endif
157
158#ifndef GET_LE32
159 #define GET_LE32( addr ) get_le32( addr )
160 #define SET_LE32( addr, data ) set_le32( addr, data )
161#endif
162
163#ifndef GET_BE16
164 #define GET_BE16( addr ) get_be16( addr )
165 #define SET_BE16( addr, data ) set_be16( addr, data )
166#endif
167
168#ifndef GET_BE32
169 #define GET_BE32( addr ) get_be32( addr )
170 #define SET_BE32( addr, data ) set_be32( addr, data )
171#endif
172
173// auto-selecting versions
174
175inline void set_le( uint16_t* p, unsigned n ) { SET_LE16( p, n ); }
176inline void set_le( uint32_t* p, blargg_ulong n ) { SET_LE32( p, n ); }
177inline void set_be( uint16_t* p, unsigned n ) { SET_BE16( p, n ); }
178inline void set_be( uint32_t* p, blargg_ulong n ) { SET_BE32( p, n ); }
179inline unsigned get_le( uint16_t* p ) { return GET_LE16( p ); }
180inline blargg_ulong get_le( uint32_t* p ) { return GET_LE32( p ); }
181inline unsigned get_be( uint16_t* p ) { return GET_BE16( p ); }
182inline blargg_ulong get_be( uint32_t* p ) { return GET_BE32( p ); }
183
184#endif
assert(0)
void set_le16(void *p, unsigned n)
Definition blargg_endian.h:95
void set_le(uint16_t *p, unsigned n)
Definition blargg_endian.h:175
#define GET_LE16(addr)
Definition blargg_endian.h:154
#define GET_BE16(addr)
Definition blargg_endian.h:164
void set_be16(void *p, unsigned n)
Definition blargg_endian.h:101
unsigned get_be(uint16_t *p)
Definition blargg_endian.h:181
unsigned get_le16(void const *p)
Definition blargg_endian.h:67
#define SET_LE16(addr, data)
Definition blargg_endian.h:155
unsigned get_be16(void const *p)
Definition blargg_endian.h:73
void blargg_verify_byte_order()
Definition blargg_endian.h:54
unsigned get_le(uint16_t *p)
Definition blargg_endian.h:179
void set_le32(void *p, blargg_ulong n)
Definition blargg_endian.h:107
void set_be(uint16_t *p, unsigned n)
Definition blargg_endian.h:177
blargg_ulong get_le32(void const *p)
Definition blargg_endian.h:79
#define GET_LE32(addr)
Definition blargg_endian.h:159
#define SET_LE32(addr, data)
Definition blargg_endian.h:160
#define SET_BE32(addr, data)
Definition blargg_endian.h:170
blargg_ulong get_be32(void const *p)
Definition blargg_endian.h:87
void set_be32(void *p, blargg_ulong n)
Definition blargg_endian.h:115
#define GET_BE32(addr)
Definition blargg_endian.h:169
#define SET_BE16(addr, data)
Definition blargg_endian.h:165
register unsigned i
Definition inflate.c:1575
unsigned short uint16_t
Definition mid.cpp:99
unsigned int uint32_t
Definition mid.cpp:100
int n
Definition crypt.c:458
uch * p
Definition crypt.c:594