| 
									
										
										
										
											2015-05-24 06:55:12 +02:00
										 |  |  | // Copyright 2009 Dolphin Emulator Project
 | 
					
						
							| 
									
										
										
										
											2015-05-18 01:08:10 +02:00
										 |  |  | // Licensed under GPLv2+
 | 
					
						
							| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-10 13:54:46 -05:00
										 |  |  | #pragma once
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-08 13:26:26 -04:00
										 |  |  | #ifdef __APPLE__
 | 
					
						
							|  |  |  | #include <libkern/OSByteOrder.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | #include <cstddef>
 | 
					
						
							| 
									
										
										
										
											2016-10-04 05:12:23 -04:00
										 |  |  | #include <cstring>
 | 
					
						
							| 
									
										
										
										
											2015-04-07 22:15:21 +02:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2014-02-19 13:46:47 -05:00
										 |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Will fail to compile on a non-array:
 | 
					
						
							| 
									
										
										
										
											2015-09-03 23:39:03 -04:00
										 |  |  | template <typename T, size_t N> | 
					
						
							|  |  |  | constexpr size_t ArraySize(T (&arr)[N]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return N; | 
					
						
							| 
									
										
										
										
											2015-09-03 23:39:03 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | #define b2(x) ((x) | ((x) >> 1))
 | 
					
						
							|  |  |  | #define b4(x) (b2(x) | (b2(x) >> 2))
 | 
					
						
							|  |  |  | #define b8(x) (b4(x) | (b4(x) >> 4))
 | 
					
						
							|  |  |  | #define b16(x) (b8(x) | (b8(x) >> 8))
 | 
					
						
							|  |  |  | #define b32(x) (b16(x) | (b16(x) >> 16))
 | 
					
						
							|  |  |  | #define ROUND_UP_POW2(x) (b32(x - 1) + 1)
 | 
					
						
							| 
									
										
										
										
											2013-10-26 19:21:00 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | #ifndef _WIN32
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-22 03:29:35 +00:00
										 |  |  | #include <errno.h>
 | 
					
						
							| 
									
										
										
										
											2009-05-01 15:17:03 +00:00
										 |  |  | #ifdef __linux__
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | #include <byteswap.h>
 | 
					
						
							| 
									
										
										
										
											2011-08-27 20:42:11 +02:00
										 |  |  | #elif defined __FreeBSD__
 | 
					
						
							|  |  |  | #include <sys/endian.h>
 | 
					
						
							| 
									
										
										
										
											2009-05-01 15:17:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-07-22 03:29:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | // go to debugger mode
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | #define Crash()                                                                                    \
 | 
					
						
							|  |  |  |   {                                                                                                \ | 
					
						
							|  |  |  |     __builtin_trap();                                                                              \ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-03 10:52:06 -05:00
										 |  |  | // GCC 4.8 defines all the rotate functions now
 | 
					
						
							| 
									
										
										
										
											2013-04-03 12:42:58 -05:00
										 |  |  | // Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit
 | 
					
						
							|  |  |  | #ifndef _rotl
 | 
					
						
							| 
									
										
										
										
											2014-08-30 16:14:56 -04:00
										 |  |  | inline u32 _rotl(u32 x, int shift) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   shift &= 31; | 
					
						
							|  |  |  |   if (!shift) | 
					
						
							|  |  |  |     return x; | 
					
						
							|  |  |  |   return (x << shift) | (x >> (32 - shift)); | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-30 16:14:56 -04:00
										 |  |  | inline u32 _rotr(u32 x, int shift) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   shift &= 31; | 
					
						
							|  |  |  |   if (!shift) | 
					
						
							|  |  |  |     return x; | 
					
						
							|  |  |  |   return (x >> shift) | (x << (32 - shift)); | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-04-03 12:42:58 -05:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-30 16:14:56 -04:00
										 |  |  | inline u64 _rotl64(u64 x, unsigned int shift) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   unsigned int n = shift % 64; | 
					
						
							|  |  |  |   return (x << n) | (x >> (64 - n)); | 
					
						
							| 
									
										
										
										
											2013-04-03 12:42:58 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-02-08 23:23:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-30 16:14:56 -04:00
										 |  |  | inline u64 _rotr64(u64 x, unsigned int shift) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   unsigned int n = shift % 64; | 
					
						
							|  |  |  |   return (x >> n) | (x << (64 - n)); | 
					
						
							| 
									
										
										
										
											2010-02-08 23:23:04 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-31 14:40:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | #else  // WIN32
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | // Function Cross-Compatibility
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | #define strcasecmp _stricmp
 | 
					
						
							|  |  |  | #define strncasecmp _strnicmp
 | 
					
						
							|  |  |  | #define unlink _unlink
 | 
					
						
							|  |  |  | #define vscprintf _vscprintf
 | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-11 00:17:29 -05:00
										 |  |  | // 64 bit offsets for Windows
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | #define fseeko _fseeki64
 | 
					
						
							|  |  |  | #define ftello _ftelli64
 | 
					
						
							|  |  |  | #define atoll _atoi64
 | 
					
						
							| 
									
										
										
										
											2016-07-17 04:30:00 -06:00
										 |  |  | #define stat _stat64
 | 
					
						
							|  |  |  | #define fstat _fstat64
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | #define fileno _fileno
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							|  |  |  | __declspec(dllimport) void __stdcall DebugBreak(void); | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | #define Crash()                                                                                    \
 | 
					
						
							|  |  |  |   {                                                                                                \ | 
					
						
							|  |  |  |     DebugBreak();                                                                                  \ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif  // WIN32 ndef
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Generic function to get last error message.
 | 
					
						
							|  |  |  | // Call directly after the command or use the error num.
 | 
					
						
							|  |  |  | // This function might change the error code.
 | 
					
						
							|  |  |  | // Defined in Misc.cpp.
 | 
					
						
							| 
									
										
										
										
											2015-04-07 22:15:21 +02:00
										 |  |  | std::string GetLastErrorMsg(); | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace Common | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | inline u8 swap8(u8 _data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return _data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | inline u32 swap24(const u8* _data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return (_data[0] << 16) | (_data[1] << 8) | _data[2]; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-17 20:18:50 -06:00
										 |  |  | #if defined(ANDROID) || defined(__OpenBSD__)
 | 
					
						
							| 
									
										
										
										
											2013-02-26 13:49:00 -06:00
										 |  |  | #undef swap16
 | 
					
						
							|  |  |  | #undef swap32
 | 
					
						
							|  |  |  | #undef swap64
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-07-11 08:58:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef _WIN32
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | inline u16 swap16(u16 _data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return _byteswap_ushort(_data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | inline u32 swap32(u32 _data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return _byteswap_ulong(_data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | inline u64 swap64(u64 _data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return _byteswap_uint64(_data); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-01-06 13:56:53 +01:00
										 |  |  | #elif __linux__
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | inline u16 swap16(u16 _data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return bswap_16(_data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | inline u32 swap32(u32 _data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return bswap_32(_data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | inline u64 swap64(u64 _data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return bswap_64(_data); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-02-16 08:46:21 +00:00
										 |  |  | #elif __APPLE__
 | 
					
						
							| 
									
										
										
										
											2010-07-18 08:30:40 +00:00
										 |  |  | inline __attribute__((always_inline)) u16 swap16(u16 _data) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return OSSwapInt16(_data); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-18 08:30:40 +00:00
										 |  |  | inline __attribute__((always_inline)) u32 swap32(u32 _data) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return OSSwapInt32(_data); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-18 08:30:40 +00:00
										 |  |  | inline __attribute__((always_inline)) u64 swap64(u64 _data) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return OSSwapInt64(_data); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-08-27 20:42:11 +02:00
										 |  |  | #elif __FreeBSD__
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | inline u16 swap16(u16 _data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return bswap16(_data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | inline u32 swap32(u32 _data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return bswap32(_data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | inline u64 swap64(u64 _data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return bswap64(_data); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | // Slow generic implementation.
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | inline u16 swap16(u16 data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return (data >> 8) | (data << 8); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | inline u32 swap32(u32 data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return (swap16(data) << 16) | swap16(data >> 16); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | inline u64 swap64(u64 data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return ((u64)swap32(data) << 32) | swap32(data >> 32); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 05:12:23 -04:00
										 |  |  | inline u16 swap16(const u8* data) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-04 05:12:23 -04:00
										 |  |  |   u16 value; | 
					
						
							|  |  |  |   std::memcpy(&value, data, sizeof(u16)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return swap16(value); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-04 05:12:23 -04:00
										 |  |  | inline u32 swap32(const u8* data) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-04 05:12:23 -04:00
										 |  |  |   u32 value; | 
					
						
							|  |  |  |   std::memcpy(&value, data, sizeof(u32)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return swap32(value); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-04 05:12:23 -04:00
										 |  |  | inline u64 swap64(const u8* data) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-04 05:12:23 -04:00
										 |  |  |   u64 value; | 
					
						
							|  |  |  |   std::memcpy(&value, data, sizeof(u64)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return swap64(value); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-20 20:20:53 -06:00
										 |  |  | template <int count> | 
					
						
							|  |  |  | void swap(u8*); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | inline void swap<1>(u8* data) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-02-20 20:20:53 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | inline void swap<2>(u8* data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-04 05:12:23 -04:00
										 |  |  |   const u16 value = swap16(data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::memcpy(data, &value, sizeof(u16)); | 
					
						
							| 
									
										
										
										
											2013-02-20 20:20:53 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | inline void swap<4>(u8* data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-04 05:12:23 -04:00
										 |  |  |   const u32 value = swap32(data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::memcpy(data, &value, sizeof(u32)); | 
					
						
							| 
									
										
										
										
											2013-02-20 20:20:53 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | inline void swap<8>(u8* data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-04 05:12:23 -04:00
										 |  |  |   const u64 value = swap64(data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::memcpy(data, &value, sizeof(u64)); | 
					
						
							| 
									
										
										
										
											2013-02-20 20:20:53 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename T> | 
					
						
							|  |  |  | inline T FromBigEndian(T data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   static_assert(std::is_arithmetic<T>::value, "function only makes sense with arithmetic types"); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   swap<sizeof(data)>(reinterpret_cast<u8*>(&data)); | 
					
						
							|  |  |  |   return data; | 
					
						
							| 
									
										
										
										
											2013-02-20 20:20:53 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-28 08:57:34 +00:00
										 |  |  | }  // Namespace Common
 |