~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Source/Core/Common/Src/CommonFuncs.h

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Dolphin Emulator Project
 
2
// Licensed under GPLv2
 
3
// Refer to the license.txt file included.
 
4
 
 
5
#ifndef _COMMONFUNCS_H_
 
6
#define _COMMONFUNCS_H_
 
7
 
 
8
#ifdef _WIN32
 
9
#define SLEEP(x) Sleep(x)
 
10
#else
 
11
#include <unistd.h>
 
12
#define SLEEP(x) usleep(x*1000)
 
13
#endif
 
14
 
 
15
#include <cstddef>
 
16
#include <type_traits>
 
17
#include "Common.h"
 
18
 
 
19
// Will fail to compile on a non-array:
 
20
// TODO: make this a function when constexpr is available
 
21
template <typename T>
 
22
struct ArraySizeImpl : public std::extent<T>
 
23
{ static_assert(std::is_array<T>::value, "is array"); };
 
24
 
 
25
#define ArraySize(x) ArraySizeImpl<decltype(x)>::value
 
26
 
 
27
#define b2(x)   (   (x) | (   (x) >> 1) )
 
28
#define b4(x)   ( b2(x) | ( b2(x) >> 2) )
 
29
#define b8(x)   ( b4(x) | ( b4(x) >> 4) )
 
30
#define b16(x)  ( b8(x) | ( b8(x) >> 8) )  
 
31
#define b32(x)  (b16(x) | (b16(x) >>16) )
 
32
#define ROUND_UP_POW2(x)        (b32(x - 1) + 1)
 
33
 
 
34
#if defined __GNUC__ && !defined __SSSE3__ && !defined _M_GENERIC
 
35
#include <emmintrin.h>
 
36
static __inline __m128i __attribute__((__always_inline__))
 
37
_mm_shuffle_epi8(__m128i a, __m128i mask)
 
38
{
 
39
        __m128i result;
 
40
        __asm__("pshufb %1, %0"
 
41
                : "=x" (result)
 
42
                : "xm" (mask), "0" (a));
 
43
        return result;
 
44
}
 
45
#endif
 
46
 
 
47
#ifndef _WIN32
 
48
 
 
49
#include <errno.h>
 
50
#ifdef __linux__
 
51
#include <byteswap.h>
 
52
#elif defined __FreeBSD__
 
53
#include <sys/endian.h>
 
54
#endif
 
55
 
 
56
// go to debugger mode
 
57
        #ifdef GEKKO
 
58
                #define Crash()
 
59
        #elif defined _M_GENERIC
 
60
                #define Crash() { exit(1); }
 
61
        #else
 
62
                #define Crash() {asm ("int $3");}
 
63
        #endif
 
64
 
 
65
// GCC 4.8 defines all the rotate functions now
 
66
// Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit
 
67
#ifndef _rotl
 
68
inline u32 _rotl(u32 x, int shift) {
 
69
        shift &= 31;
 
70
        if (!shift) return x;
 
71
        return (x << shift) | (x >> (32 - shift));
 
72
}
 
73
 
 
74
inline u32 _rotr(u32 x, int shift) {
 
75
        shift &= 31;
 
76
        if (!shift) return x;
 
77
        return (x >> shift) | (x << (32 - shift));
 
78
}
 
79
#endif
 
80
 
 
81
inline u64 _rotl64(u64 x, unsigned int shift){
 
82
        unsigned int n = shift % 64;
 
83
        return (x << n) | (x >> (64 - n));
 
84
}
 
85
 
 
86
inline u64 _rotr64(u64 x, unsigned int shift){
 
87
        unsigned int n = shift % 64;
 
88
        return (x >> n) | (x << (64 - n));
 
89
}
 
90
 
 
91
#else // WIN32
 
92
// Function Cross-Compatibility
 
93
        #define strcasecmp _stricmp
 
94
        #define strncasecmp _strnicmp
 
95
        #define unlink _unlink
 
96
        #define snprintf _snprintf
 
97
        #define vscprintf _vscprintf
 
98
        
 
99
// Locale Cross-Compatibility
 
100
        #define locale_t _locale_t
 
101
        #define freelocale _free_locale
 
102
        #define newlocale(mask, locale, base) _create_locale(mask, locale)
 
103
        
 
104
        #define LC_GLOBAL_LOCALE        ((locale_t)-1)
 
105
        #define LC_ALL_MASK                     LC_ALL
 
106
        #define LC_COLLATE_MASK         LC_COLLATE
 
107
        #define LC_CTYPE_MASK           LC_CTYPE
 
108
        #define LC_MONETARY_MASK        LC_MONETARY
 
109
        #define LC_NUMERIC_MASK         LC_NUMERIC
 
110
        #define LC_TIME_MASK            LC_TIME
 
111
        
 
112
        inline locale_t uselocale(locale_t new_locale)
 
113
        {
 
114
                // Retrieve the current per thread locale setting
 
115
                bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE);
 
116
 
 
117
                // Retrieve the current thread-specific locale
 
118
                locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE;
 
119
 
 
120
                if(new_locale == LC_GLOBAL_LOCALE)
 
121
                {
 
122
                        // Restore the global locale
 
123
                        _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
 
124
                }
 
125
                else if(new_locale != NULL)
 
126
                {
 
127
                        // Configure the thread to set the locale only for this thread
 
128
                        _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
 
129
 
 
130
                        // Set all locale categories
 
131
                        for(int i = LC_MIN; i <= LC_MAX; i++)
 
132
                                setlocale(i, new_locale->locinfo->lc_category[i].locale);
 
133
                }
 
134
 
 
135
                return old_locale;
 
136
        }
 
137
 
 
138
// 64 bit offsets for windows
 
139
        #define fseeko _fseeki64
 
140
        #define ftello _ftelli64
 
141
        #define atoll _atoi64
 
142
        #define stat64 _stat64
 
143
        #define fstat64 _fstat64
 
144
        #define fileno _fileno
 
145
 
 
146
        #if _M_IX86
 
147
                #define Crash() {__asm int 3}
 
148
        #else
 
149
extern "C" {
 
150
        __declspec(dllimport) void __stdcall DebugBreak(void);
 
151
}
 
152
                #define Crash() {DebugBreak();}
 
153
        #endif // M_IX86
 
154
#endif // WIN32 ndef
 
155
 
 
156
// Dolphin's min and max functions
 
157
#undef min
 
158
#undef max
 
159
 
 
160
template<class T>
 
161
inline T min(const T& a, const T& b) {return a > b ? b : a;}
 
162
template<class T>
 
163
inline T max(const T& a, const T& b) {return a > b ? a : b;}
 
164
 
 
165
// Generic function to get last error message.
 
166
// Call directly after the command or use the error num.
 
167
// This function might change the error code.
 
168
// Defined in Misc.cpp.
 
169
const char* GetLastErrorMsg();
 
170
 
 
171
namespace Common
 
172
{
 
173
inline u8 swap8(u8 _data) {return _data;}
 
174
inline u32 swap24(const u8* _data) {return (_data[0] << 16) | (_data[1] << 8) | _data[2];}
 
175
 
 
176
#ifdef ANDROID
 
177
#undef swap16
 
178
#undef swap32
 
179
#undef swap64
 
180
#endif
 
181
 
 
182
#ifdef _WIN32
 
183
inline u16 swap16(u16 _data) {return _byteswap_ushort(_data);}
 
184
inline u32 swap32(u32 _data) {return _byteswap_ulong (_data);}
 
185
inline u64 swap64(u64 _data) {return _byteswap_uint64(_data);}
 
186
#elif _M_ARM
 
187
inline u16 swap16 (u16 _data) { u32 data = _data; __asm__ ("rev16 %0, %1\n" : "=l" (data) : "l" (data)); return (u16)data;} 
 
188
inline u32 swap32 (u32 _data) {__asm__ ("rev %0, %1\n" : "=l" (_data) : "l" (_data)); return _data;} 
 
189
inline u64 swap64(u64 _data) {return ((u64)swap32(_data) << 32) | swap32(_data >> 32);}
 
190
#elif __linux__
 
191
inline u16 swap16(u16 _data) {return bswap_16(_data);}
 
192
inline u32 swap32(u32 _data) {return bswap_32(_data);}
 
193
inline u64 swap64(u64 _data) {return bswap_64(_data);}
 
194
#elif __APPLE__
 
195
inline __attribute__((always_inline)) u16 swap16(u16 _data)
 
196
        {return (_data >> 8) | (_data << 8);}
 
197
inline __attribute__((always_inline)) u32 swap32(u32 _data)
 
198
        {return __builtin_bswap32(_data);}
 
199
inline __attribute__((always_inline)) u64 swap64(u64 _data)
 
200
        {return __builtin_bswap64(_data);}
 
201
#elif __FreeBSD__
 
202
inline u16 swap16(u16 _data) {return bswap16(_data);}
 
203
inline u32 swap32(u32 _data) {return bswap32(_data);}
 
204
inline u64 swap64(u64 _data) {return bswap64(_data);}
 
205
#else
 
206
// Slow generic implementation.
 
207
inline u16 swap16(u16 data) {return (data >> 8) | (data << 8);}
 
208
inline u32 swap32(u32 data) {return (swap16(data) << 16) | swap16(data >> 16);}
 
209
inline u64 swap64(u64 data) {return ((u64)swap32(data) << 32) | swap32(data >> 32);}
 
210
#endif
 
211
 
 
212
inline u16 swap16(const u8* _pData) {return swap16(*(const u16*)_pData);}
 
213
inline u32 swap32(const u8* _pData) {return swap32(*(const u32*)_pData);}
 
214
inline u64 swap64(const u8* _pData) {return swap64(*(const u64*)_pData);}
 
215
 
 
216
template <int count>
 
217
void swap(u8*);
 
218
 
 
219
template <>
 
220
inline void swap<1>(u8* data)
 
221
{}
 
222
 
 
223
template <>
 
224
inline void swap<2>(u8* data)
 
225
{
 
226
        *reinterpret_cast<u16*>(data) = swap16(data);
 
227
}
 
228
 
 
229
template <>
 
230
inline void swap<4>(u8* data)
 
231
{
 
232
        *reinterpret_cast<u32*>(data) = swap32(data);
 
233
}
 
234
 
 
235
template <>
 
236
inline void swap<8>(u8* data)
 
237
{
 
238
        *reinterpret_cast<u64*>(data) = swap64(data);
 
239
}
 
240
 
 
241
template <typename T>
 
242
inline T FromBigEndian(T data)
 
243
{
 
244
        //static_assert(std::is_arithmetic<T>::value, "function only makes sense with arithmetic types");
 
245
        
 
246
        swap<sizeof(data)>(reinterpret_cast<u8*>(&data));
 
247
        return data;
 
248
}
 
249
 
 
250
}  // Namespace Common
 
251
 
 
252
#endif // _COMMONFUNCS_H_