| 
									
										
										
										
											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>
 | 
					
						
							| 
									
										
										
										
											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]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return N; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-09-11 19:19:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-20 15:50:33 -08:00
										 |  |  | #define b2(x)   (   (x) | (   (x) >> 1) )
 | 
					
						
							|  |  |  | #define b4(x)   ( b2(x) | ( b2(x) >> 2) )
 | 
					
						
							|  |  |  | #define b8(x)   ( b4(x) | ( b4(x) >> 4) )
 | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | #define b16(x)  ( b8(x) | ( b8(x) >> 8) )
 | 
					
						
							| 
									
										
										
										
											2011-11-20 15:50:33 -08:00
										 |  |  | #define b32(x)  (b16(x) | (b16(x) >>16) )
 | 
					
						
							| 
									
										
										
										
											2014-02-09 18:29:13 -05:00
										 |  |  | #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
 | 
					
						
							| 
									
										
										
										
											2015-11-19 00:49:42 -06: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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-03-19 21:51:12 -04: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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-03-19 21:51:12 -04: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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-04-03 12:42:58 -05:00
										 |  |  | 	unsigned int n = shift % 64; | 
					
						
							|  |  |  | 	return (x << n) | (x >> (64 - n)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-02-08 23:23:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-30 16:14:56 -04:00
										 |  |  | inline u64 _rotr64(u64 x, unsigned int shift) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-08 23:23:04 +00:00
										 |  |  | 	unsigned int n = shift % 64; | 
					
						
							|  |  |  | 	return (x >> n) | (x << (64 - n)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-31 14:40:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | #else // WIN32
 | 
					
						
							|  |  |  | // Function Cross-Compatibility
 | 
					
						
							|  |  |  | 	#define strcasecmp _stricmp
 | 
					
						
							|  |  |  | 	#define strncasecmp _strnicmp
 | 
					
						
							|  |  |  | 	#define unlink _unlink
 | 
					
						
							| 
									
										
										
										
											2009-11-08 08:54:09 +00:00
										 |  |  | 	#define vscprintf _vscprintf
 | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-11 00:17:29 -05:00
										 |  |  | // 64 bit offsets for Windows
 | 
					
						
							| 
									
										
										
										
											2010-12-04 03:50:55 +00:00
										 |  |  | 	#define fseeko _fseeki64
 | 
					
						
							|  |  |  | 	#define ftello _ftelli64
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 	#define atoll _atoi64
 | 
					
						
							|  |  |  | 	#define stat64 _stat64
 | 
					
						
							| 
									
										
										
										
											2010-12-03 12:42:01 +00:00
										 |  |  | 	#define fstat64 _fstat64
 | 
					
						
							|  |  |  | 	#define fileno _fileno
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-03 13:42:06 -05:00
										 |  |  | extern "C" | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 	__declspec(dllimport) void __stdcall DebugBreak(void); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-08-03 13:42:06 -05:00
										 |  |  | 	#define Crash() {DebugBreak();}
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | #endif // WIN32 ndef
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 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 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | inline u8 swap8(u8 _data) {return _data;} | 
					
						
							| 
									
										
										
										
											2013-05-31 07:12:59 +02:00
										 |  |  | inline u32 swap24(const u8* _data) {return (_data[0] << 16) | (_data[1] << 8) | _data[2];} | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-26 13:49:00 -06:00
										 |  |  | #ifdef ANDROID
 | 
					
						
							|  |  |  | #undef swap16
 | 
					
						
							|  |  |  | #undef swap32
 | 
					
						
							|  |  |  | #undef swap64
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-07-11 08:58:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef _WIN32
 | 
					
						
							|  |  |  | 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);} | 
					
						
							| 
									
										
										
										
											2014-11-30 01:07:12 -06:00
										 |  |  | #elif __linux__ && !(ANDROID && _M_ARM_64)
 | 
					
						
							|  |  |  | // Android NDK r10c has broken builtin byte swap routines
 | 
					
						
							|  |  |  | // Disabled for now.
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00: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) | 
					
						
							| 
									
										
										
										
											2014-08-08 13:26:26 -04:00
										 |  |  | 	{return OSSwapInt16(_data);} | 
					
						
							| 
									
										
										
										
											2010-07-18 08:30:40 +00:00
										 |  |  | inline __attribute__((always_inline)) u32 swap32(u32 _data) | 
					
						
							| 
									
										
										
										
											2014-08-08 13:26:26 -04:00
										 |  |  | 	{return OSSwapInt32(_data);} | 
					
						
							| 
									
										
										
										
											2010-07-18 08:30:40 +00:00
										 |  |  | inline __attribute__((always_inline)) u64 swap64(u64 _data) | 
					
						
							| 
									
										
										
										
											2014-08-08 13:26:26 -04:00
										 |  |  | 	{return OSSwapInt64(_data);} | 
					
						
							| 
									
										
										
										
											2011-08-27 20:42:11 +02:00
										 |  |  | #elif __FreeBSD__
 | 
					
						
							|  |  |  | 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.
 | 
					
						
							|  |  |  | 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);} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline u16 swap16(const u8* _pData) {return swap16(*(const u16*)_pData);} | 
					
						
							|  |  |  | inline u32 swap32(const u8* _pData) {return swap32(*(const u32*)_pData);} | 
					
						
							|  |  |  | inline u64 swap64(const u8* _pData) {return swap64(*(const u64*)_pData);} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-20 20:20:53 -06:00
										 |  |  | template <int count> | 
					
						
							|  |  |  | void swap(u8*); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | inline void swap<1>(u8* data) | 
					
						
							|  |  |  | {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | inline void swap<2>(u8* data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	*reinterpret_cast<u16*>(data) = swap16(data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | inline void swap<4>(u8* data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	*reinterpret_cast<u32*>(data) = swap32(data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | inline void swap<8>(u8* data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	*reinterpret_cast<u64*>(data) = swap64(data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename T> | 
					
						
							|  |  |  | inline T FromBigEndian(T data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-03 00:14:53 +13:00
										 |  |  | 	static_assert(std::is_arithmetic<T>::value, "function only makes sense with arithmetic types"); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-20 20:20:53 -06:00
										 |  |  | 	swap<sizeof(data)>(reinterpret_cast<u8*>(&data)); | 
					
						
							|  |  |  | 	return data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-28 08:57:34 +00:00
										 |  |  | }  // Namespace Common
 |