|
146 | 146 | */
|
147 | 147 | #define MKTAG(a0,a1,a2,a3) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24)))
|
148 | 148 |
|
149 |
| -// Functions for reading/writing native Integers, |
150 |
| -// this transparently handles the need for alignment |
151 |
| - |
152 |
| -#if !defined(SCUMM_NEED_ALIGNMENT) |
| 149 | +// Functions for reading/writing native integers. |
| 150 | +// They also transparently handle the need for alignment. |
| 151 | + |
| 152 | +// Test for GCC >= 4.0. These implementations will automatically use |
| 153 | +// CPU-specific instructions for unaligned data when they are available (eg. |
| 154 | +// MIPS). See also this email thread on scummvm-devel for details: |
| 155 | +// <http://thread.gmane.org/gmane.games.devel.scummvm/8063> |
| 156 | +// |
| 157 | +// Moreover, we activate this code for GCC >= 3.3 but *only* if unaligned access |
| 158 | +// is allowed. |
| 159 | +#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3 && !defined(SCUMM_NEED_ALIGNMENT))) |
153 | 160 |
|
154 | 161 | FORCEINLINE uint16 READ_UINT16(const void *ptr) {
|
155 |
| - return *(const uint16 *)(ptr); |
| 162 | + struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__)); |
| 163 | + return ((const Unaligned16 *)ptr)->val; |
156 | 164 | }
|
157 | 165 |
|
158 | 166 | FORCEINLINE uint32 READ_UINT32(const void *ptr) {
|
159 |
| - return *(const uint32 *)(ptr); |
| 167 | + struct Unaligned32 { uint32 val; } __attribute__ ((__packed__, __may_alias__)); |
| 168 | + return ((const Unaligned32 *)ptr)->val; |
160 | 169 | }
|
161 | 170 |
|
162 | 171 | FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
|
163 |
| - *(uint16 *)(ptr) = value; |
| 172 | + struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__)); |
| 173 | + ((Unaligned16 *)ptr)->val = value; |
164 | 174 | }
|
165 | 175 |
|
166 | 176 | FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) {
|
167 |
| - *(uint32 *)(ptr) = value; |
| 177 | + struct Unaligned32 { uint32 val; } __attribute__ ((__packed__, __may_alias__)); |
| 178 | + ((Unaligned32 *)ptr)->val = value; |
168 | 179 | }
|
169 | 180 |
|
170 |
| -// test for GCC >= 4.0. these implementations will automatically use CPU-specific |
171 |
| -// instructions for unaligned data when they are available (eg. MIPS) |
172 |
| -#elif defined(__GNUC__) && (__GNUC__ >= 4) |
| 181 | +#elif !defined(SCUMM_NEED_ALIGNMENT) |
173 | 182 |
|
174 | 183 | FORCEINLINE uint16 READ_UINT16(const void *ptr) {
|
175 |
| - struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__)); |
176 |
| - return ((const Unaligned16 *)ptr)->val; |
| 184 | + return *(const uint16 *)(ptr); |
177 | 185 | }
|
178 | 186 |
|
179 | 187 | FORCEINLINE uint32 READ_UINT32(const void *ptr) {
|
180 |
| - struct Unaligned32 { uint32 val; } __attribute__ ((__packed__, __may_alias__)); |
181 |
| - return ((const Unaligned32 *)ptr)->val; |
| 188 | + return *(const uint32 *)(ptr); |
182 | 189 | }
|
183 | 190 |
|
184 | 191 | FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
|
185 |
| - struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__)); |
186 |
| - ((Unaligned16 *)ptr)->val = value; |
| 192 | + *(uint16 *)(ptr) = value; |
187 | 193 | }
|
188 | 194 |
|
189 | 195 | FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) {
|
190 |
| - struct Unaligned32 { uint32 val; } __attribute__ ((__packed__, __may_alias__)); |
191 |
| - ((Unaligned32 *)ptr)->val = value; |
| 196 | + *(uint32 *)(ptr) = value; |
192 | 197 | }
|
193 | 198 |
|
| 199 | + |
194 | 200 | // use software fallback by loading each byte explicitely
|
195 | 201 | #else
|
196 | 202 |
|
@@ -390,6 +396,7 @@ inline uint32 READ_BE_UINT24(const void *ptr) {
|
390 | 396 | return (b[0] << 16) | (b[1] << 8) | (b[2]);
|
391 | 397 | }
|
392 | 398 |
|
| 399 | +// ResidualVM specific: |
393 | 400 | #if defined(SCUMM_BIG_ENDIAN)
|
394 | 401 |
|
395 | 402 | inline float get_float(const char *data) {
|
|
0 commit comments