Merge pull request #1659 from PCSX2/greg/clang-format-common

reformat main common directory
This commit is contained in:
Gregory Hainaut 2016-11-14 11:37:53 +01:00 committed by GitHub
commit 259521ec3e
137 changed files with 15017 additions and 14373 deletions

File diff suppressed because it is too large Load Diff

View File

@ -55,8 +55,7 @@ static void __forceinline PluginNullConfigure(std::wstring desc, s32 &log);
static void __forceinline PluginNullAbout(const wchar_t *aboutText);
#endif
enum FileMode
{
enum FileMode {
READ_FILE = 0,
WRITE_FILE
};
@ -70,9 +69,8 @@ struct PluginLog
{
LogFile = fopen(logname.c_str(), "w");
if (LogFile)
{
setvbuf(LogFile, NULL, _IONBF, 0);
if (LogFile) {
setvbuf(LogFile, NULL, _IONBF, 0);
return true;
}
return false;
@ -90,11 +88,14 @@ struct PluginLog
{
va_list list;
if (LogFile == NULL) return;
if (LogFile == NULL)
return;
va_start(list, fmt);
if (WriteToFile) vfprintf(LogFile, fmt, list);
if (WriteToConsole) vfprintf(stdout, fmt, list);
if (WriteToFile)
vfprintf(LogFile, fmt, list);
if (WriteToConsole)
vfprintf(stdout, fmt, list);
va_end(list);
}
@ -102,15 +103,20 @@ struct PluginLog
{
va_list list;
if (LogFile == NULL) return;
if (LogFile == NULL)
return;
va_start(list, fmt);
if (WriteToFile) vfprintf(LogFile, fmt, list);
if (WriteToConsole) vfprintf(stdout, fmt, list);
if (WriteToFile)
vfprintf(LogFile, fmt, list);
if (WriteToConsole)
vfprintf(stdout, fmt, list);
va_end(list);
if (WriteToFile) fprintf(LogFile, "\n");
if (WriteToConsole) fprintf(stdout, "\n");
if (WriteToFile)
fprintf(LogFile, "\n");
if (WriteToConsole)
fprintf(stdout, "\n");
}
#if !defined(_MSC_VER) || !defined(UNICODE)
@ -119,7 +125,8 @@ struct PluginLog
va_list list;
char buf[256];
if (LogFile == NULL) return;
if (LogFile == NULL)
return;
va_start(list, fmt);
vsprintf(buf, fmt, list);
@ -128,19 +135,20 @@ struct PluginLog
SysMessage(buf);
}
#else
void Message(const wchar_t *fmt, ...)
{
va_list list;
wchar_t buf[256];
void Message(const wchar_t *fmt, ...)
{
va_list list;
wchar_t buf[256];
if (LogFile == NULL) return;
if (LogFile == NULL)
return;
va_start(list, fmt);
vswprintf(buf, 256, fmt, list);
va_end(list);
va_start(list, fmt);
vswprintf(buf, 256, fmt, list);
va_end(list);
SysMessage(buf);
}
SysMessage(buf);
}
#endif
};
@ -151,16 +159,14 @@ struct PluginConf
bool Open(std::string name, FileMode mode = READ_FILE)
{
if (mode == READ_FILE)
{
if (mode == READ_FILE) {
ConfFile = fopen(name.c_str(), "r");
}
else
{
} else {
ConfFile = fopen(name.c_str(), "w");
}
if (ConfFile == NULL) return false;
if (ConfFile == NULL)
return false;
return true;
}
@ -173,14 +179,14 @@ struct PluginConf
}
}
int ReadInt(const std::string& item, int defval)
int ReadInt(const std::string &item, int defval)
{
int value = defval;
std::string buf = item + " = %d\n";
if (ConfFile)
if (fscanf(ConfFile, buf.c_str(), &value) < 0)
fprintf(stderr, "Error reading %s\n", item.c_str());
if (fscanf(ConfFile, buf.c_str(), &value) < 0)
fprintf(stderr, "Error reading %s\n", item.c_str());
return value;
}
@ -189,7 +195,8 @@ struct PluginConf
{
std::string buf = item + " = %d\n";
if (ConfFile) fprintf(ConfFile, buf.c_str(), value);
if (ConfFile)
fprintf(ConfFile, buf.c_str(), value);
}
};
@ -204,19 +211,20 @@ static void SysMessage(const char *fmt, ...)
vsprintf(msg, fmt, list);
va_end(list);
if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0;
if (msg[strlen(msg) - 1] == '\n')
msg[strlen(msg) - 1] = 0;
GtkWidget *dialog;
dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
"%s", msg);
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
dialog = gtk_message_dialog_new(NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
"%s", msg);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
static void __forceinline set_logging(GtkToggleButton *check, int& log)
static void __forceinline set_logging(GtkToggleButton *check, int &log)
{
log = gtk_toggle_button_get_active(check);
}
@ -227,7 +235,7 @@ static void __forceinline PluginNullConfigure(std::string desc, int &log)
/* Create the widgets */
dialog = gtk_dialog_new();
label = gtk_label_new (desc.c_str());
label = gtk_label_new(desc.c_str());
check_box = gtk_check_button_new_with_label("Logging");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), (log != 0));
@ -236,14 +244,14 @@ static void __forceinline PluginNullConfigure(std::string desc, int &log)
g_signal_connect(check_box, "toggled", G_CALLBACK(set_logging), &log);
/* Add all our widgets, and show everything we've added to the dialog. */
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area(GTK_DIALOG(dialog))), label);
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area(GTK_DIALOG(dialog))), check_box);
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), label);
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), check_box);
gtk_dialog_add_button(GTK_DIALOG(dialog), "Ok", 0);
gtk_widget_show_all (dialog);
gtk_widget_show_all(dialog);
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
static void __forceinline PluginNullAbout(const char *aboutText)
@ -265,7 +273,8 @@ static void SysMessage(const char *fmt, ...)
vsprintf(msg, fmt, list);
va_end(list);
if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0;
if (msg[strlen(msg) - 1] == '\n')
msg[strlen(msg) - 1] = 0;
// TODO OSX can we use WX MessageBox here or should Cocoa MessageBox used?
}
@ -297,7 +306,7 @@ static void __forceinline PluginNullAbout(const char *aboutText)
#else
#define usleep(x) Sleep(x / 1000)
#define usleep(x) Sleep(x / 1000)
#ifndef UNICODE
@ -305,15 +314,15 @@ static void __forceinline SysMessage(const char *fmt, ...)
{
va_list list;
char tmp[512];
va_start(list,fmt);
vsprintf(tmp,fmt,list);
va_start(list, fmt);
vsprintf(tmp, fmt, list);
va_end(list);
MessageBox( GetActiveWindow(), tmp, "Message", MB_SETFOREGROUND | MB_OK );
MessageBox(GetActiveWindow(), tmp, "Message", MB_SETFOREGROUND | MB_OK);
}
static void __forceinline PluginNullConfigure(std::string desc, s32 &log)
{
/* To do: Write a dialog box that displays a dialog box with the text in desc,
/* To do: Write a dialog box that displays a dialog box with the text in desc,
and a check box that says "Logging", checked if log !=0, and set log to
1 if it is checked on return, and 0 if it isn't. */
SysMessage("This space is intentionally left blank.");
@ -327,39 +336,39 @@ static void __forceinline PluginNullAbout(const char *aboutText)
static void __forceinline SysMessage(const wchar_t *fmt, ...)
{
va_list list;
wchar_t tmp[512];
va_start(list, fmt);
vswprintf(tmp, 512, fmt, list);
va_end(list);
MessageBox(GetActiveWindow(), tmp, L"Message", MB_SETFOREGROUND | MB_OK);
va_list list;
wchar_t tmp[512];
va_start(list, fmt);
vswprintf(tmp, 512, fmt, list);
va_end(list);
MessageBox(GetActiveWindow(), tmp, L"Message", MB_SETFOREGROUND | MB_OK);
}
static void __forceinline PluginNullConfigure(std::string desc, s32 &log)
{
/* To do: Write a dialog box that displays a dialog box with the text in desc,
/* To do: Write a dialog box that displays a dialog box with the text in desc,
and a check box that says "Logging", checked if log !=0, and set log to
1 if it is checked on return, and 0 if it isn't. */
SysMessage(L"This space is intentionally left blank.");
SysMessage(L"This space is intentionally left blank.");
}
static void __forceinline PluginNullAbout(const wchar_t *aboutText)
{
SysMessage(aboutText);
SysMessage(aboutText);
}
#endif
#define ENTRY_POINT \
HINSTANCE hInst; \
\
BOOL APIENTRY DllMain(HANDLE hModule, /* DLL INIT*/ \
DWORD dwReason, \
LPVOID lpReserved) \
{ \
hInst = (HINSTANCE)hModule; \
return TRUE; /* very quick :)*/ \
}
#define ENTRY_POINT \
HINSTANCE hInst; \
\
BOOL APIENTRY DllMain(HANDLE hModule, /* DLL INIT*/ \
DWORD dwReason, \
LPVOID lpReserved) \
{ \
hInst = (HINSTANCE)hModule; \
return TRUE; /* very quick :)*/ \
}
#endif
#endif // PS2EEXT_H_INCLUDED

View File

@ -13,7 +13,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// This file is just for backwards compatibility.
// This file is just for backwards compatibility.
#ifndef __PS2ETYPES_H__
#define __PS2ETYPES_H__

View File

@ -35,64 +35,71 @@
#ifdef _MSC_VER
#define EXPORT_C(type) extern "C" type CALLBACK
#else
#define EXPORT_C(type) extern "C" __attribute__((externally_visible,visibility("default"))) type
#define EXPORT_C(type) extern "C" __attribute__((externally_visible, visibility("default"))) type
#endif
EXPORT_C(u32) PS2EgetLibType(void);
EXPORT_C(u32) PS2EgetLibVersion2(u32 type);
EXPORT_C(char*) PS2EgetLibName(void);
EXPORT_C(u32)
PS2EgetLibType(void);
EXPORT_C(u32)
PS2EgetLibVersion2(u32 type);
EXPORT_C(char *)
PS2EgetLibName(void);
// Extended functions.
// allows the plugin to see the whole configuration when started up.
// Intended for them to get the ini and plugin paths, but could allow for other things as well.
EXPORT_C_(void) PS2EpassConfig(PcsxConfig Config);
EXPORT_C_(void)
PS2EpassConfig(PcsxConfig Config);
// Alternately, this function serves the same purpose, but would work for emulators outside
// of pcsx2.
EXPORT_C_(void) PS2EpassIniPath(const char *path);
EXPORT_C_(void)
PS2EpassIniPath(const char *path);
// PS2EgetLibType returns (may be OR'd)
enum {
PS2E_LT_GS = 0x01,
PS2E_LT_PAD = 0x02, // -=[ OBSOLETE ]=-
PS2E_LT_SPU2 = 0x04,
PS2E_LT_CDVD = 0x08,
PS2E_LT_DEV9 = 0x10,
PS2E_LT_USB = 0x20,
PS2E_LT_FW = 0x40,
PS2E_LT_SIO = 0x80
PS2E_LT_GS = 0x01,
PS2E_LT_PAD = 0x02, // -=[ OBSOLETE ]=-
PS2E_LT_SPU2 = 0x04,
PS2E_LT_CDVD = 0x08,
PS2E_LT_DEV9 = 0x10,
PS2E_LT_USB = 0x20,
PS2E_LT_FW = 0x40,
PS2E_LT_SIO = 0x80
} PluginLibType;
// PS2EgetLibVersion2 (high 16 bits)
enum {
PS2E_GS_VERSION = 0x0006,
PS2E_PAD_VERSION = 0x0002, // -=[ OBSOLETE ]=-
PS2E_SPU2_VERSION = 0x0005,
PS2E_CDVD_VERSION = 0x0005,
PS2E_DEV9_VERSION = 0x0003,
PS2E_USB_VERSION = 0x0003,
PS2E_FW_VERSION = 0x0002,
PS2E_SIO_VERSION = 0x0001
PS2E_GS_VERSION = 0x0006,
PS2E_PAD_VERSION = 0x0002, // -=[ OBSOLETE ]=-
PS2E_SPU2_VERSION = 0x0005,
PS2E_CDVD_VERSION = 0x0005,
PS2E_DEV9_VERSION = 0x0003,
PS2E_USB_VERSION = 0x0003,
PS2E_FW_VERSION = 0x0002,
PS2E_SIO_VERSION = 0x0001
} PluginLibVersion;
// freeze modes:
enum {
FREEZE_LOAD = 0,
FREEZE_SAVE = 1,
FREEZE_SIZE = 2
FREEZE_LOAD = 0,
FREEZE_SAVE = 1,
FREEZE_SIZE = 2
} FreezeModes;
typedef struct _GSdriverInfo {
char name[8];
void *common;
typedef struct _GSdriverInfo
{
char name[8];
void *common;
} GSdriverInfo;
#ifdef _MSC_VER
typedef struct _winInfo { // unsupported values must be set to zero
HWND hWnd;
HMENU hMenu;
HWND hStatusWnd;
typedef struct _winInfo
{ // unsupported values must be set to zero
HWND hWnd;
HMENU hMenu;
HWND hStatusWnd;
} winInfo;
#endif

View File

@ -26,9 +26,9 @@
// make sure __POSIX__ is defined for all systems where we assume POSIX
// compliance
#if defined(__linux__) || defined(__APPLE__) || defined(__unix__) || defined(__CYGWIN__) || defined(__LINUX__)
# if !defined(__POSIX__)
# define __POSIX__ 1
# endif
#if !defined(__POSIX__)
#define __POSIX__ 1
#endif
#endif
#include "Pcsx2Types.h"
@ -39,7 +39,7 @@
// Notes: I'd have used ARRAY_SIZE instead but ran into cross-platform lib conflicts with
// that as well. >_<
#ifndef ArraySize
# define ArraySize(x) (sizeof(x)/sizeof((x)[0]))
#define ArraySize(x) (sizeof(x) / sizeof((x)[0]))
#endif
// --------------------------------------------------------------------------------------
@ -51,51 +51,51 @@
// some tight loops it will likely make debug builds unusably slow.
//
#ifdef __cplusplus
# ifdef PCSX2_DEVBUILD
static const bool IsDevBuild = true;
# else
static const bool IsDevBuild = false;
# endif
# ifdef PCSX2_DEBUG
static const bool IsDebugBuild = true;
# else
static const bool IsDebugBuild = false;
# endif
#ifdef PCSX2_DEVBUILD
static const bool IsDevBuild = true;
#else
# ifdef PCSX2_DEVBUILD
static const u8 IsDevBuild = 1;
# else
static const u8 IsDevBuild = 0;
# endif
# ifdef PCSX2_DEBUG
static const u8 IsDebugBuild = 1;
# else
static const u8 IsDebugBuild = 0;
# endif
static const bool IsDevBuild = false;
#endif
#ifdef PCSX2_DEBUG
# define pxDebugCode(code) code
static const bool IsDebugBuild = true;
#else
# define pxDebugCode(code)
static const bool IsDebugBuild = false;
#endif
#else
#ifdef PCSX2_DEVBUILD
static const u8 IsDevBuild = 1;
#else
static const u8 IsDevBuild = 0;
#endif
#ifdef PCSX2_DEBUG
static const u8 IsDebugBuild = 1;
#else
static const u8 IsDebugBuild = 0;
#endif
#endif
#ifdef PCSX2_DEBUG
#define pxDebugCode(code) code
#else
#define pxDebugCode(code)
#endif
#ifdef PCSX2_DEVBUILD
# define pxDevelCode(code) code
#define pxDevelCode(code) code
#else
# define pxDevelCode(code)
#define pxDevelCode(code)
#endif
#if defined(PCSX2_DEBUG) || defined(PCSX2_DEVBUILD)
# define pxReleaseCode(code)
# define pxNonReleaseCode(code) code
#define pxReleaseCode(code)
#define pxNonReleaseCode(code) code
#else
# define pxReleaseCode(code) code
# define pxNonReleaseCode(code)
#define pxReleaseCode(code) code
#define pxNonReleaseCode(code)
#endif
// --------------------------------------------------------------------------------------
@ -116,8 +116,8 @@
// Defines the memory page size for the target platform at compilation. All supported platforms
// (which means Intel only right now) have a 4k granularity.
#define PCSX2_PAGESIZE 0x1000
static const int __pagesize = PCSX2_PAGESIZE;
#define PCSX2_PAGESIZE 0x1000
static const int __pagesize = PCSX2_PAGESIZE;
// --------------------------------------------------------------------------------------
// Structure Packing (__packed)
@ -154,27 +154,27 @@ static const int __pagesize = PCSX2_PAGESIZE;
// This is the 2005/earlier compatible packing define, which must be used in conjunction
// with #ifdef _MSC_VER/#pragma pack() directives (ugly).
# define __packed
#define __packed
# define __aligned(alig) __declspec(align(alig))
# define __aligned16 __declspec(align(16))
# define __aligned32 __declspec(align(32))
# define __pagealigned __declspec(align(PCSX2_PAGESIZE))
#define __aligned(alig) __declspec(align(alig))
#define __aligned16 __declspec(align(16))
#define __aligned32 __declspec(align(32))
#define __pagealigned __declspec(align(PCSX2_PAGESIZE))
// Deprecated; use __align instead.
# define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
# define PCSX2_ALIGNED_EXTERN(alig,x) extern __declspec(align(alig)) x
# define PCSX2_ALIGNED16(x) __declspec(align(16)) x
# define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
// Deprecated; use __align instead.
#define PCSX2_ALIGNED(alig, x) __declspec(align(alig)) x
#define PCSX2_ALIGNED_EXTERN(alig, x) extern __declspec(align(alig)) x
#define PCSX2_ALIGNED16(x) __declspec(align(16)) x
#define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
# define __noinline __declspec(noinline)
# define __threadlocal __declspec(thread)
#define __noinline __declspec(noinline)
#define __threadlocal __declspec(thread)
// Don't know if there are Visual C++ equivalents of these.
# define likely(x) (!!(x))
# define unlikely(x) (!!(x))
#define likely(x) (!!(x))
#define unlikely(x) (!!(x))
# define CALLBACK __stdcall
#define CALLBACK __stdcall
#else
@ -183,42 +183,42 @@ static const int __pagesize = PCSX2_PAGESIZE;
// --------------------------------------------------------------------------------------
#ifndef __packed
# define __packed __attribute__((packed))
#define __packed __attribute__((packed))
#endif
#ifndef __aligned
# define __aligned(alig) __attribute__((aligned(alig)))
#define __aligned(alig) __attribute__((aligned(alig)))
#endif
# define __aligned16 __attribute__((aligned(16)))
# define __aligned32 __attribute__((aligned(32)))
# define __pagealigned __attribute__((aligned(PCSX2_PAGESIZE)))
// Deprecated; use __align instead.
# define PCSX2_ALIGNED(alig,x) x __attribute((aligned(alig)))
# define PCSX2_ALIGNED16(x) x __attribute((aligned(16)))
# define PCSX2_ALIGNED_EXTERN(alig,x) extern x __attribute((aligned(alig)))
# define PCSX2_ALIGNED16_EXTERN(x) extern x __attribute((aligned(16)))
#define __aligned16 __attribute__((aligned(16)))
#define __aligned32 __attribute__((aligned(32)))
#define __pagealigned __attribute__((aligned(PCSX2_PAGESIZE)))
// Deprecated; use __align instead.
#define PCSX2_ALIGNED(alig, x) x __attribute((aligned(alig)))
#define PCSX2_ALIGNED16(x) x __attribute((aligned(16)))
#define PCSX2_ALIGNED_EXTERN(alig, x) extern x __attribute((aligned(alig)))
#define PCSX2_ALIGNED16_EXTERN(x) extern x __attribute((aligned(16)))
# define __assume(cond) ((void)0) // GCC has no equivalent for __assume
# define CALLBACK __attribute__((stdcall))
#define __assume(cond) ((void)0) // GCC has no equivalent for __assume
#define CALLBACK __attribute__((stdcall))
// Inlining note: GCC needs ((unused)) attributes defined on inlined functions to suppress
// warnings when a static inlined function isn't used in the scope of a single file (which
// happens *by design* like all the friggen time >_<)
#ifndef __fastcall
# define __fastcall __attribute__((fastcall))
#define __fastcall __attribute__((fastcall))
#endif
#define _inline __inline__ __attribute__((unused))
#ifdef NDEBUG
#define __forceinline __attribute__((always_inline, unused))
#else
#define __forceinline __attribute__((unused))
#endif
# define _inline __inline__ __attribute__((unused))
# ifdef NDEBUG
# define __forceinline __attribute__((always_inline,unused))
# else
# define __forceinline __attribute__((unused))
# endif
#ifndef __noinline
# define __noinline __attribute__((noinline))
#define __noinline __attribute__((noinline))
#endif
# define __threadlocal __thread
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
#define __threadlocal __thread
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
// --------------------------------------------------------------------------------------
@ -233,13 +233,13 @@ static const int __pagesize = PCSX2_PAGESIZE;
// environment.
//
#ifdef PCSX2_DEVBUILD
# define __releaseinline
#define __releaseinline
#else
# define __releaseinline __forceinline
#define __releaseinline __forceinline
#endif
#define __ri __releaseinline
#define __fi __forceinline
#define __fc __fastcall
#define __ri __releaseinline
#define __fi __forceinline
#define __fc __fastcall
#endif

View File

@ -24,9 +24,9 @@
// depend on these types will not be usable (they will yield linker errors).
#ifdef __cplusplus
class wxString;
class FastFormatAscii;
class FastFormatUnicode;
class wxString;
class FastFormatAscii;
class FastFormatUnicode;
#endif
@ -65,116 +65,116 @@ typedef unsigned int uint;
#ifdef __cplusplus
union u128
{
struct
{
u64 lo;
u64 hi;
};
struct
{
u64 lo;
u64 hi;
};
u64 _u64[2];
u32 _u32[4];
u16 _u16[8];
u8 _u8[16];
u64 _u64[2];
u32 _u32[4];
u16 _u16[8];
u8 _u8[16];
// Explicit conversion from u64. Zero-extends the source through 128 bits.
static u128 From64( u64 src )
{
u128 retval;
retval.lo = src;
retval.hi = 0;
return retval;
}
// Explicit conversion from u64. Zero-extends the source through 128 bits.
static u128 From64(u64 src)
{
u128 retval;
retval.lo = src;
retval.hi = 0;
return retval;
}
// Explicit conversion from u32. Zero-extends the source through 128 bits.
static u128 From32( u32 src )
{
u128 retval;
retval._u32[0] = src;
retval._u32[1] = 0;
retval.hi = 0;
return retval;
}
// Explicit conversion from u32. Zero-extends the source through 128 bits.
static u128 From32(u32 src)
{
u128 retval;
retval._u32[0] = src;
retval._u32[1] = 0;
retval.hi = 0;
return retval;
}
operator u32() const { return _u32[0]; }
operator u16() const { return _u16[0]; }
operator u8() const { return _u8[0]; }
bool operator==( const u128& right ) const
{
return (lo == right.lo) && (hi == right.hi);
}
operator u32() const { return _u32[0]; }
operator u16() const { return _u16[0]; }
operator u8() const { return _u8[0]; }
bool operator!=( const u128& right ) const
{
return (lo != right.lo) || (hi != right.hi);
}
bool operator==(const u128 &right) const
{
return (lo == right.lo) && (hi == right.hi);
}
// In order for the following ToString() and WriteTo methods to be available, you must
// be linking to both wxWidgets and the pxWidgets extension library. If you are not
// using them, then you will need to provide your own implementations of these methods.
wxString ToString() const;
wxString ToString64() const;
wxString ToString8() const;
void WriteTo( FastFormatAscii& dest ) const;
void WriteTo8( FastFormatAscii& dest ) const;
void WriteTo64( FastFormatAscii& dest ) const;
bool operator!=(const u128 &right) const
{
return (lo != right.lo) || (hi != right.hi);
}
// In order for the following ToString() and WriteTo methods to be available, you must
// be linking to both wxWidgets and the pxWidgets extension library. If you are not
// using them, then you will need to provide your own implementations of these methods.
wxString ToString() const;
wxString ToString64() const;
wxString ToString8() const;
void WriteTo(FastFormatAscii &dest) const;
void WriteTo8(FastFormatAscii &dest) const;
void WriteTo64(FastFormatAscii &dest) const;
};
struct s128
{
s64 lo;
s64 hi;
s64 lo;
s64 hi;
// explicit conversion from s64, with sign extension.
static s128 From64( s64 src )
{
s128 retval = { src, (src < 0) ? -1 : 0 };
return retval;
}
// explicit conversion from s64, with sign extension.
static s128 From64(s64 src)
{
s128 retval = {src, (src < 0) ? -1 : 0};
return retval;
}
// explicit conversion from s32, with sign extension.
static s128 From64( s32 src )
{
s128 retval = { src, (src < 0) ? -1 : 0 };
return retval;
}
// explicit conversion from s32, with sign extension.
static s128 From64(s32 src)
{
s128 retval = {src, (src < 0) ? -1 : 0};
return retval;
}
operator u32() const { return (s32)lo; }
operator u16() const { return (s16)lo; }
operator u8() const { return (s8)lo; }
operator u32() const { return (s32)lo; }
operator u16() const { return (s16)lo; }
operator u8() const { return (s8)lo; }
bool operator==( const s128& right ) const
{
return (lo == right.lo) && (hi == right.hi);
}
bool operator==(const s128 &right) const
{
return (lo == right.lo) && (hi == right.hi);
}
bool operator!=( const s128& right ) const
{
return (lo != right.lo) || (hi != right.hi);
}
bool operator!=(const s128 &right) const
{
return (lo != right.lo) || (hi != right.hi);
}
};
#else
typedef union _u128_t
{
struct
{
u64 lo;
u64 hi;
};
struct
{
u64 lo;
u64 hi;
};
u64 _u64[2];
u32 _u32[4];
u16 _u16[8];
u8 _u8[16];
u64 _u64[2];
u32 _u32[4];
u16 _u16[8];
u8 _u8[16];
} u128;
typedef union _s128_t
{
u64 lo;
s64 hi;
u64 lo;
s64 hi;
} s128;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -27,14 +27,13 @@
//
class Pcsx2AppTraits : public wxGUIAppTraits
{
typedef wxGUIAppTraits _parent;
typedef wxGUIAppTraits _parent;
public:
virtual ~Pcsx2AppTraits() {}
wxMessageOutput* CreateMessageOutput();
virtual ~Pcsx2AppTraits() {}
wxMessageOutput *CreateMessageOutput();
#ifdef wxUSE_STDPATHS
wxStandardPaths& GetStandardPaths();
wxStandardPaths &GetStandardPaths();
#endif
};

View File

@ -17,14 +17,14 @@
#ifndef __pxFUNCTION__
#if defined(__GNUG__)
# define __pxFUNCTION__ __PRETTY_FUNCTION__
#define __pxFUNCTION__ __PRETTY_FUNCTION__
#else
# define __pxFUNCTION__ __FUNCTION__
#define __pxFUNCTION__ __FUNCTION__
#endif
#endif
#ifndef wxNullChar
# define wxNullChar ((wxChar*)NULL)
#define wxNullChar ((wxChar *)NULL)
#endif
// FnChar_t - function name char type; typedef'd in case it ever changes between compilers
@ -36,29 +36,29 @@ typedef char FnChar_t;
// --------------------------------------------------------------------------------------
struct DiagnosticOrigin
{
const wxChar* srcfile;
const FnChar_t* function;
const wxChar* condition;
int line;
const wxChar *srcfile;
const FnChar_t *function;
const wxChar *condition;
int line;
DiagnosticOrigin( const wxChar *_file, int _line, const FnChar_t *_func, const wxChar* _cond = NULL )
: srcfile( _file )
, function( _func )
, condition( _cond )
, line( _line )
{
}
DiagnosticOrigin(const wxChar *_file, int _line, const FnChar_t *_func, const wxChar *_cond = NULL)
: srcfile(_file)
, function(_func)
, condition(_cond)
, line(_line)
{
}
wxString ToString( const wxChar* msg=NULL ) const;
wxString ToString(const wxChar *msg = NULL) const;
};
// Returns ture if the assertion is to trap into the debugger, or false if execution
// of the program should continue unimpeded.
typedef bool pxDoAssertFnType(const DiagnosticOrigin& origin, const wxChar *msg);
typedef bool pxDoAssertFnType(const DiagnosticOrigin &origin, const wxChar *msg);
extern pxDoAssertFnType pxAssertImpl_LogIt;
extern pxDoAssertFnType* pxDoAssert;
extern pxDoAssertFnType *pxDoAssert;
// ----------------------------------------------------------------------------------------
// pxAssert / pxAssertDev
@ -97,95 +97,99 @@ extern pxDoAssertFnType* pxDoAssert;
// it can lead to the compiler optimizing out code and leading to crashes in dev/release
// builds. To have code optimized, explicitly use pxAssume(false) or pxAssumeDev(false,msg);
#define pxDiagSpot DiagnosticOrigin( __TFILE__, __LINE__, __pxFUNCTION__ )
#define pxAssertSpot(cond) DiagnosticOrigin( __TFILE__, __LINE__, __pxFUNCTION__, _T(#cond) )
#define pxDiagSpot DiagnosticOrigin(__TFILE__, __LINE__, __pxFUNCTION__)
#define pxAssertSpot(cond) DiagnosticOrigin(__TFILE__, __LINE__, __pxFUNCTION__, _T(#cond))
// pxAssertRel ->
// Special release-mode assertion. Limited use since stack traces in release mode builds
// (especially with LTCG) are highly suspect. But when troubleshooting crashes that only
// rear ugly heads in optimized builds, this is one of the few tools we have.
#define pxAssertRel(cond, msg) ( (likely(cond)) || (pxOnAssert(pxAssertSpot(cond), msg), false) )
#define pxAssumeRel(cond, msg) ((void) ( (!likely(cond)) && (pxOnAssert(pxAssertSpot(cond), msg), false) ))
#define pxFailRel(msg) pxAssertRel(false, msg)
#define pxAssertRel(cond, msg) ((likely(cond)) || (pxOnAssert(pxAssertSpot(cond), msg), false))
#define pxAssumeRel(cond, msg) ((void)((!likely(cond)) && (pxOnAssert(pxAssertSpot(cond), msg), false)))
#define pxFailRel(msg) pxAssertRel(false, msg)
#if defined(PCSX2_DEBUG)
# define pxAssertMsg(cond, msg) pxAssertRel(cond, msg)
# define pxAssertDev(cond, msg) pxAssertMsg(cond, msg)
#define pxAssertMsg(cond, msg) pxAssertRel(cond, msg)
#define pxAssertDev(cond, msg) pxAssertMsg(cond, msg)
# define pxAssumeMsg(cond, msg) pxAssumeRel(cond, msg)
# define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg)
#define pxAssumeMsg(cond, msg) pxAssumeRel(cond, msg)
#define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg)
# define pxFail(msg) pxAssertMsg(false, msg)
# define pxFailDev(msg) pxAssertDev(false, msg)
#define pxFail(msg) pxAssertMsg(false, msg)
#define pxFailDev(msg) pxAssertDev(false, msg)
#elif defined(PCSX2_DEVBUILD)
// Devel builds now will give you a release-mode assertion dialog window if any of the
// following macro's 'cond' field is false.
// Note: Only use pxAssume/Msg/Dev if you know what you're doing, __assume is supposed
// to be used as an optimization hint, yet many devs have been using psAssume
// thinking its the same as an assertion.
// __assume(0) is also very dangerous because it is a special case of __assume() which
// tells the compiler that the code path is not reachable, and it can cause unpredictable
// results if the code path can be reached.
// i.e. if (1) { __assume(0); something(); }
// In the above example, something() may never be called.
// __assume(0)'s real use is in optimizing stuff such as "default:" cases on a switch
// statement. See jNO_DEFAULT
// Devel builds now will give you a release-mode assertion dialog window if any of the
// following macro's 'cond' field is false.
// Note: Only use pxAssume/Msg/Dev if you know what you're doing, __assume is supposed
// to be used as an optimization hint, yet many devs have been using psAssume
// thinking its the same as an assertion.
// __assume(0) is also very dangerous because it is a special case of __assume() which
// tells the compiler that the code path is not reachable, and it can cause unpredictable
// results if the code path can be reached.
// i.e. if (1) { __assume(0); something(); }
// In the above example, something() may never be called.
// __assume(0)'s real use is in optimizing stuff such as "default:" cases on a switch
// statement. See jNO_DEFAULT
# define pxAssertMsg(cond, msg) pxAssertRel(cond, msg)
# define pxAssertDev(cond, msg) pxAssertRel(cond, msg)
#define pxAssertMsg(cond, msg) pxAssertRel(cond, msg)
#define pxAssertDev(cond, msg) pxAssertRel(cond, msg)
# define pxAssumeMsg(cond, msg) pxAssumeRel(cond, msg) //(__assume(cond))
# define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg)
#define pxAssumeMsg(cond, msg) pxAssumeRel(cond, msg) //(__assume(cond))
#define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg)
# define pxFail(msg) pxAssertDev(false, msg)
# define pxFailDev(msg) pxAssertDev(false, msg)
#define pxFail(msg) pxAssertDev(false, msg)
#define pxFailDev(msg) pxAssertDev(false, msg)
#else
// Release Builds just use __assume as an optimization, and return the conditional
// as a result (which is optimized to nil if unused).
// Release Builds just use __assume as an optimization, and return the conditional
// as a result (which is optimized to nil if unused).
# define pxAssertMsg(cond, msg) (likely(cond))
# define pxAssertDev(cond, msg) (likely(cond))
#define pxAssertMsg(cond, msg) (likely(cond))
#define pxAssertDev(cond, msg) (likely(cond))
# define pxAssumeMsg(cond, msg) (__assume(cond))
# define pxAssumeDev(cond, msg) (__assume(cond))
#define pxAssumeMsg(cond, msg) (__assume(cond))
#define pxAssumeDev(cond, msg) (__assume(cond))
# define pxFail(msg) do{} while(0)
# define pxFailDev(msg) do{} while(0)
#define pxFail(msg) \
do { \
} while (0)
#define pxFailDev(msg) \
do { \
} while (0)
#endif
#define pxAssert(cond) pxAssertMsg(cond, wxNullChar)
#define pxAssume(cond) pxAssumeMsg(cond, wxNullChar)
#define pxAssert(cond) pxAssertMsg(cond, wxNullChar)
#define pxAssume(cond) pxAssumeMsg(cond, wxNullChar)
#define pxAssertRelease( cond, msg )
#define pxAssertRelease(cond, msg)
// Performs an unsigned index bounds check, and generates a debug assertion if the check fails.
// For stricter checking in Devel builds as well as debug builds (but possibly slower), use
// IndexBoundsCheckDev.
#define IndexBoundsCheck( objname, idx, sze ) pxAssertMsg( (uint)(idx) < (uint)(sze), \
pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
#define IndexBoundsCheck(objname, idx, sze) pxAssertMsg((uint)(idx) < (uint)(sze), \
pxsFmt(L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze)))
#define IndexBoundsCheckDev( objname, idx, sze ) pxAssertDev( (uint)(idx) < (uint)(sze), \
pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
#define IndexBoundsCheckDev(objname, idx, sze) pxAssertDev((uint)(idx) < (uint)(sze), \
pxsFmt(L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze)))
#define IndexBoundsAssume( objname, idx, sze ) pxAssumeMsg( (uint)(idx) < (uint)(sze), \
pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
#define IndexBoundsAssume(objname, idx, sze) pxAssumeMsg((uint)(idx) < (uint)(sze), \
pxsFmt(L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze)))
#define IndexBoundsAssumeDev( objname, idx, sze ) pxAssumeDev( (uint)(idx) < (uint)(sze), \
pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
#define IndexBoundsAssumeDev(objname, idx, sze) pxAssumeDev((uint)(idx) < (uint)(sze), \
pxsFmt(L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze)))
extern void pxOnAssert( const DiagnosticOrigin& origin, const wxChar* msg=NULL );
extern void pxOnAssert( const DiagnosticOrigin& origin, const char* msg );
extern void pxOnAssert( const DiagnosticOrigin& origin, const wxString& msg);
extern void pxOnAssert( const DiagnosticOrigin& origin, const FastFormatUnicode& msg);
extern void pxOnAssert(const DiagnosticOrigin &origin, const wxChar *msg = NULL);
extern void pxOnAssert(const DiagnosticOrigin &origin, const char *msg);
extern void pxOnAssert(const DiagnosticOrigin &origin, const wxString &msg);
extern void pxOnAssert(const DiagnosticOrigin &origin, const FastFormatUnicode &msg);
// --------------------------------------------------------------------------------------
// jNO_DEFAULT -- disables the default case in a switch, which improves switch optimization
@ -198,10 +202,9 @@ extern void pxOnAssert( const DiagnosticOrigin& origin, const FastFormatUnicode&
// * In debug/devel builds the default case will cause an assertion.
//
#ifndef jNO_DEFAULT
# define jNO_DEFAULT \
default: \
{ \
pxAssumeDev( 0, "Incorrect usage of jNO_DEFAULT detected (default case is not unreachable!)" ); \
break; \
}
#define jNO_DEFAULT \
default: { \
pxAssumeDev(0, "Incorrect usage of jNO_DEFAULT detected (default case is not unreachable!)"); \
break; \
}
#endif

View File

@ -19,19 +19,19 @@
class CheckedStaticBox : public wxPanelWithHelpers
{
typedef wxPanelWithHelpers _parent;
typedef wxPanelWithHelpers _parent;
public:
wxBoxSizer& ThisSizer; // Boxsizer which holds all child items.
wxCheckBox& ThisToggle; // toggle which can enable/disable all child controls
wxBoxSizer &ThisSizer; // Boxsizer which holds all child items.
wxCheckBox &ThisToggle; // toggle which can enable/disable all child controls
public:
CheckedStaticBox( wxWindow* parent, int orientation, const wxString& title=wxEmptyString );
CheckedStaticBox(wxWindow *parent, int orientation, const wxString &title = wxEmptyString);
void SetValue(bool val);
bool GetValue() const;
bool Enable(bool enable = true);
void SetValue( bool val );
bool GetValue() const;
bool Enable( bool enable = true );
public:
virtual void MainToggle_Click( wxCommandEvent& evt );
virtual void MainToggle_Click(wxCommandEvent &evt);
};

View File

@ -17,46 +17,45 @@
#include "StringHelpers.h"
enum ConsoleColors
{
Color_Current = -1,
enum ConsoleColors {
Color_Current = -1,
Color_Default = 0,
Color_Default = 0,
Color_Black,
Color_Green,
Color_Red,
Color_Blue,
Color_Magenta,
Color_Orange,
Color_Gray,
Color_Black,
Color_Green,
Color_Red,
Color_Blue,
Color_Magenta,
Color_Orange,
Color_Gray,
Color_Cyan, // faint visibility, intended for logging PS2/IOP output
Color_Yellow, // faint visibility, intended for logging PS2/IOP output
Color_White, // faint visibility, intended for logging PS2/IOP output
Color_Cyan, // faint visibility, intended for logging PS2/IOP output
Color_Yellow, // faint visibility, intended for logging PS2/IOP output
Color_White, // faint visibility, intended for logging PS2/IOP output
// Strong text *may* result in mis-aligned text in the console, depending on the
// font and the platform, so use these with caution.
Color_StrongBlack,
Color_StrongRed, // intended for errors
Color_StrongGreen, // intended for infrequent state information
Color_StrongBlue, // intended for block headings
Color_StrongMagenta,
Color_StrongOrange, // intended for warnings
Color_StrongGray,
// Strong text *may* result in mis-aligned text in the console, depending on the
// font and the platform, so use these with caution.
Color_StrongBlack,
Color_StrongRed, // intended for errors
Color_StrongGreen, // intended for infrequent state information
Color_StrongBlue, // intended for block headings
Color_StrongMagenta,
Color_StrongOrange, // intended for warnings
Color_StrongGray,
Color_StrongCyan,
Color_StrongYellow,
Color_StrongWhite,
Color_StrongCyan,
Color_StrongYellow,
Color_StrongWhite,
ConsoleColors_Count
ConsoleColors_Count
};
static const ConsoleColors DefaultConsoleColor = Color_Default;
// Use fastcall for the console; should be helpful in most cases
#define __concall __fastcall
#define __concall __fastcall
// ----------------------------------------------------------------------------------------
// IConsoleWriter -- For printing messages to the console.
@ -71,60 +70,60 @@ static const ConsoleColors DefaultConsoleColor = Color_Default;
//
struct IConsoleWriter
{
// A direct console write, without tabbing or newlines. Useful to devs who want to do quick
// logging of various junk; but should *not* be used in production code due.
void (__concall *WriteRaw)( const wxString& fmt );
// A direct console write, without tabbing or newlines. Useful to devs who want to do quick
// logging of various junk; but should *not* be used in production code due.
void(__concall *WriteRaw)(const wxString &fmt);
// WriteLn implementation for internal use only. Bypasses tabbing, prefixing, and other
// formatting.
void (__concall *DoWriteLn)( const wxString& fmt );
// WriteLn implementation for internal use only. Bypasses tabbing, prefixing, and other
// formatting.
void(__concall *DoWriteLn)(const wxString &fmt);
// SetColor implementation for internal use only.
void (__concall *DoSetColor)( ConsoleColors color );
// SetColor implementation for internal use only.
void(__concall *DoSetColor)(ConsoleColors color);
// Special implementation of DoWrite that's pretty much for MSVC use only.
// All implementations should map to DoWrite, except Stdio which should map to Null.
// (This avoids circular/recursive stdio output)
void (__concall *DoWriteFromStdout)( const wxString& fmt );
// Special implementation of DoWrite that's pretty much for MSVC use only.
// All implementations should map to DoWrite, except Stdio which should map to Null.
// (This avoids circular/recursive stdio output)
void(__concall *DoWriteFromStdout)(const wxString &fmt);
void (__concall *Newline)();
void (__concall *SetTitle)( const wxString& title );
void(__concall *Newline)();
void(__concall *SetTitle)(const wxString &title);
// internal value for indentation of individual lines. Use the Indent() member to invoke.
int _imm_indentation;
// internal value for indentation of individual lines. Use the Indent() member to invoke.
int _imm_indentation;
// For internal use only.
wxString _addIndentation( const wxString& src, int glob_indent ) const;
// For internal use only.
wxString _addIndentation(const wxString &src, int glob_indent) const;
// ----------------------------------------------------------------------------
// Public members; call these to print stuff to console!
//
// All functions always return false. Return value is provided only so that we can easily
// disable logs at compile time using the "0&&action" macro trick.
// ----------------------------------------------------------------------------
// Public members; call these to print stuff to console!
//
// All functions always return false. Return value is provided only so that we can easily
// disable logs at compile time using the "0&&action" macro trick.
ConsoleColors GetColor() const;
const IConsoleWriter& SetColor( ConsoleColors color ) const;
const IConsoleWriter& ClearColor() const;
const IConsoleWriter& SetIndent( int tabcount=1 ) const;
ConsoleColors GetColor() const;
const IConsoleWriter &SetColor(ConsoleColors color) const;
const IConsoleWriter &ClearColor() const;
const IConsoleWriter &SetIndent(int tabcount = 1) const;
IConsoleWriter Indent( int tabcount=1 ) const;
IConsoleWriter Indent(int tabcount = 1) const;
bool FormatV( const char* fmt, va_list args ) const;
bool WriteLn( ConsoleColors color, const char* fmt, ... ) const;
bool WriteLn( const char* fmt, ... ) const;
bool Error( const char* fmt, ... ) const;
bool Warning( const char* fmt, ... ) const;
bool FormatV(const char *fmt, va_list args) const;
bool WriteLn(ConsoleColors color, const char *fmt, ...) const;
bool WriteLn(const char *fmt, ...) const;
bool Error(const char *fmt, ...) const;
bool Warning(const char *fmt, ...) const;
bool FormatV( const wxChar* fmt, va_list args ) const;
bool WriteLn( ConsoleColors color, const wxChar* fmt, ... ) const;
bool WriteLn( const wxChar* fmt, ... ) const;
bool Error( const wxChar* fmt, ... ) const;
bool Warning( const wxChar* fmt, ... ) const;
bool FormatV(const wxChar *fmt, va_list args) const;
bool WriteLn(ConsoleColors color, const wxChar *fmt, ...) const;
bool WriteLn(const wxChar *fmt, ...) const;
bool Error(const wxChar *fmt, ...) const;
bool Warning(const wxChar *fmt, ...) const;
bool WriteLn( ConsoleColors color, const wxString fmt, ... ) const;
bool WriteLn( const wxString fmt, ... ) const;
bool Error( const wxString fmt, ... ) const;
bool Warning( const wxString fmt, ... ) const;
bool WriteLn(ConsoleColors color, const wxString fmt, ...) const;
bool WriteLn(const wxString fmt, ...) const;
bool Error(const wxString fmt, ...) const;
bool Warning(const wxString fmt, ...) const;
};
// --------------------------------------------------------------------------------------
@ -134,37 +133,37 @@ struct IConsoleWriter
//
struct NullConsoleWriter
{
void WriteRaw( const wxString& fmt ) {}
void DoWriteLn( const wxString& fmt ) {}
void DoSetColor( ConsoleColors color ) {}
void DoWriteFromStdout( const wxString& fmt ) {}
void Newline() {}
void SetTitle( const wxString& title ) {}
void WriteRaw(const wxString &fmt) {}
void DoWriteLn(const wxString &fmt) {}
void DoSetColor(ConsoleColors color) {}
void DoWriteFromStdout(const wxString &fmt) {}
void Newline() {}
void SetTitle(const wxString &title) {}
ConsoleColors GetColor() const { return Color_Current; }
const NullConsoleWriter& SetColor( ConsoleColors color ) const { return *this; }
const NullConsoleWriter& ClearColor() const { return *this; }
const NullConsoleWriter& SetIndent( int tabcount=1 ) const { return *this; }
ConsoleColors GetColor() const { return Color_Current; }
const NullConsoleWriter &SetColor(ConsoleColors color) const { return *this; }
const NullConsoleWriter &ClearColor() const { return *this; }
const NullConsoleWriter &SetIndent(int tabcount = 1) const { return *this; }
NullConsoleWriter Indent( int tabcount=1 ) const { return NullConsoleWriter(); }
NullConsoleWriter Indent(int tabcount = 1) const { return NullConsoleWriter(); }
bool FormatV( const char* fmt, va_list args ) const { return false; }
bool WriteLn( ConsoleColors color, const char* fmt, ... ) const { return false; }
bool WriteLn( const char* fmt, ... ) const { return false; }
bool Error( const char* fmt, ... ) const { return false; }
bool Warning( const char* fmt, ... ) const { return false; }
bool FormatV(const char *fmt, va_list args) const { return false; }
bool WriteLn(ConsoleColors color, const char *fmt, ...) const { return false; }
bool WriteLn(const char *fmt, ...) const { return false; }
bool Error(const char *fmt, ...) const { return false; }
bool Warning(const char *fmt, ...) const { return false; }
bool FormatV( const wxChar* fmt, va_list args ) const { return false; }
bool WriteLn( ConsoleColors color, const wxChar* fmt, ... ) const { return false; }
bool WriteLn( const wxChar* fmt, ... ) const { return false; }
bool Error( const wxChar* fmt, ... ) const { return false; }
bool Warning( const wxChar* fmt, ... ) const { return false; }
bool FormatV(const wxChar *fmt, va_list args) const { return false; }
bool WriteLn(ConsoleColors color, const wxChar *fmt, ...) const { return false; }
bool WriteLn(const wxChar *fmt, ...) const { return false; }
bool Error(const wxChar *fmt, ...) const { return false; }
bool Warning(const wxChar *fmt, ...) const { return false; }
bool WriteLn( ConsoleColors color, const wxString fmt, ... ) const { return false; }
bool WriteLn( const wxString fmt, ... ) const { return false; }
bool Error( const wxString fmt, ... ) const { return false; }
bool Warning( const wxString fmt, ... ) const { return false; }
bool WriteLn(ConsoleColors color, const wxString fmt, ...) const { return false; }
bool WriteLn(const wxString fmt, ...) const { return false; }
bool Error(const wxString fmt, ...) const { return false; }
bool Warning(const wxString fmt, ...) const { return false; }
};
// --------------------------------------------------------------------------------------
@ -180,19 +179,19 @@ struct NullConsoleWriter
//
class ConsoleIndentScope
{
DeclareNoncopyableObject( ConsoleIndentScope );
DeclareNoncopyableObject(ConsoleIndentScope);
protected:
int m_amount;
bool m_IsScoped;
int m_amount;
bool m_IsScoped;
public:
// Constructor: The specified number of tabs will be appended to the current indentation
// setting. The tabs will be unrolled when the object leaves scope or is destroyed.
ConsoleIndentScope( int tabs=1 );
virtual ~ConsoleIndentScope() throw();
void EnterScope();
void LeaveScope();
// Constructor: The specified number of tabs will be appended to the current indentation
// setting. The tabs will be unrolled when the object leaves scope or is destroyed.
ConsoleIndentScope(int tabs = 1);
virtual ~ConsoleIndentScope() throw();
void EnterScope();
void LeaveScope();
};
// --------------------------------------------------------------------------------------
@ -200,18 +199,18 @@ public:
// --------------------------------------------------------------------------------------
class ConsoleColorScope
{
DeclareNoncopyableObject( ConsoleColorScope );
DeclareNoncopyableObject(ConsoleColorScope);
protected:
ConsoleColors m_newcolor;
ConsoleColors m_old_color;
bool m_IsScoped;
ConsoleColors m_newcolor;
ConsoleColors m_old_color;
bool m_IsScoped;
public:
ConsoleColorScope( ConsoleColors newcolor );
virtual ~ConsoleColorScope() throw();
void EnterScope();
void LeaveScope();
ConsoleColorScope(ConsoleColors newcolor);
virtual ~ConsoleColorScope() throw();
void EnterScope();
void LeaveScope();
};
// --------------------------------------------------------------------------------------
@ -221,42 +220,42 @@ public:
//
class ConsoleAttrScope
{
DeclareNoncopyableObject( ConsoleAttrScope );
DeclareNoncopyableObject(ConsoleAttrScope);
protected:
ConsoleColors m_old_color;
int m_tabsize;
ConsoleColors m_old_color;
int m_tabsize;
public:
ConsoleAttrScope( ConsoleColors newcolor, int indent=0 );
virtual ~ConsoleAttrScope() throw();
ConsoleAttrScope(ConsoleColors newcolor, int indent = 0);
virtual ~ConsoleAttrScope() throw();
};
extern IConsoleWriter Console;
extern IConsoleWriter Console;
#if defined(__unix__)
extern void Console_SetStdout(FILE *fp);
#endif
extern void Console_SetActiveHandler( const IConsoleWriter& writer, FILE* flushfp=NULL );
extern void Console_SetActiveHandler(const IConsoleWriter &writer, FILE *flushfp = NULL);
extern const IConsoleWriter ConsoleWriter_Null;
extern const IConsoleWriter ConsoleWriter_Stdout;
extern const IConsoleWriter ConsoleWriter_Assert;
extern const IConsoleWriter ConsoleWriter_Null;
extern const IConsoleWriter ConsoleWriter_Stdout;
extern const IConsoleWriter ConsoleWriter_Assert;
extern NullConsoleWriter NullCon;
extern NullConsoleWriter NullCon;
extern IConsoleWriter DevConWriter;
extern bool DevConWriterEnabled;
extern IConsoleWriter DevConWriter;
extern bool DevConWriterEnabled;
#ifdef PCSX2_DEVBUILD
# define DevCon DevConWriter
#define DevCon DevConWriter
#else
# define DevCon DevConWriterEnabled && DevConWriter
#define DevCon DevConWriterEnabled &&DevConWriter
#endif
#ifdef PCSX2_DEBUG
extern IConsoleWriter DbgConWriter;
# define DbgCon DbgConWriter
extern IConsoleWriter DbgConWriter;
#define DbgCon DbgConWriter
#else
# define DbgCon 0&&NullCon
#define DbgCon 0 && NullCon
#endif

View File

@ -24,19 +24,19 @@
#define wxsFormat wxString::Format
#ifdef PCSX2_DEBUG
# define tryDEBUG try
# define catchDEBUG(clause) catch(clause)
#define tryDEBUG try
#define catchDEBUG(clause) catch (clause)
#else
# define tryDEBUG if(true)
# define catchDEBUG(clause) if(false)
#define tryDEBUG if (true)
#define catchDEBUG(clause) if (false)
#endif
#if defined(PCSX2_DEVBUILD) || defined(PCSX2_DEBUG)
# define tryDEVEL try
# define catchDEVEL catch(clause)
#define tryDEVEL try
#define catchDEVEL catch (clause)
#else
# define tryDEBUG if(true)
# define catchDEBUG(clause) if(false)
#define tryDEBUG if (true)
#define catchDEBUG(clause) if (false)
#endif
// --------------------------------------------------------------------------------------
@ -61,24 +61,48 @@
// method is not implemented! You must implement it yourself if you want to use it:
// EnumToString(value);
//
#define ImplementEnumOperators( enumName ) \
static __fi enumName& operator++ ( enumName& src ) { src = (enumName)((int)src+1); return src; } \
static __fi enumName& operator-- ( enumName& src ) { src = (enumName)((int)src-1); return src; } \
static __fi enumName operator++ ( enumName& src, int ) { enumName orig = src; src = (enumName)((int)src+1); return orig; } \
static __fi enumName operator-- ( enumName& src, int ) { enumName orig = src; src = (enumName)((int)src-1); return orig; } \
\
static __fi bool operator< ( const enumName& left, const pxEnumEnd_t& ) { return (int)left < enumName##_COUNT; } \
static __fi bool operator!=( const enumName& left, const pxEnumEnd_t& ) { return (int)left != enumName##_COUNT; } \
static __fi bool operator==( const enumName& left, const pxEnumEnd_t& ) { return (int)left == enumName##_COUNT; } \
\
static __fi bool EnumIsValid( enumName id ) { \
return ((int)id >= enumName##_FIRST) && ((int)id < enumName##_COUNT); } \
static __fi void EnumAssert( enumName id ) { \
pxAssert( EnumIsValid(id) ); } \
\
extern const wxChar* EnumToString( enumName id )
#define ImplementEnumOperators(enumName) \
static __fi enumName &operator++(enumName &src) \
{ \
src = (enumName)((int)src + 1); \
return src; \
} \
static __fi enumName &operator--(enumName &src) \
{ \
src = (enumName)((int)src - 1); \
return src; \
} \
static __fi enumName operator++(enumName &src, int) \
{ \
enumName orig = src; \
src = (enumName)((int)src + 1); \
return orig; \
} \
static __fi enumName operator--(enumName &src, int) \
{ \
enumName orig = src; \
src = (enumName)((int)src - 1); \
return orig; \
} \
\
static __fi bool operator<(const enumName &left, const pxEnumEnd_t &) { return (int)left < enumName##_COUNT; } \
static __fi bool operator!=(const enumName &left, const pxEnumEnd_t &) { return (int)left != enumName##_COUNT; } \
static __fi bool operator==(const enumName &left, const pxEnumEnd_t &) { return (int)left == enumName##_COUNT; } \
\
static __fi bool EnumIsValid(enumName id) \
{ \
return ((int)id >= enumName##_FIRST) && ((int)id < enumName##_COUNT); \
} \
static __fi void EnumAssert(enumName id) \
{ \
pxAssert(EnumIsValid(id)); \
} \
\
extern const wxChar *EnumToString(enumName id)
class pxEnumEnd_t { };
class pxEnumEnd_t
{
};
static const pxEnumEnd_t pxEnumEnd = {};
// --------------------------------------------------------------------------------------
@ -105,10 +129,10 @@ static const pxEnumEnd_t pxEnumEnd = {};
// of wx dependencies though, and has a nicer typeset. :)
//
#ifndef DeclareNoncopyableObject
# define DeclareNoncopyableObject(classname) \
private: \
explicit classname(const classname&); \
classname& operator=(const classname&)
#define DeclareNoncopyableObject(classname) \
private: \
explicit classname(const classname &); \
classname &operator=(const classname &)
#endif
@ -120,19 +144,19 @@ static const pxEnumEnd_t pxEnumEnd = {};
class ScopedBool
{
protected:
bool* m_boolme;
bool *m_boolme;
public:
ScopedBool(bool& boolme)
{
boolme = true;
m_boolme = &boolme;
}
ScopedBool(bool &boolme)
{
boolme = true;
m_boolme = &boolme;
}
~ScopedBool() throw()
{
*m_boolme = false;
}
~ScopedBool() throw()
{
*m_boolme = false;
}
};
// --------------------------------------------------------------------------------------
@ -149,15 +173,15 @@ public:
#define WXINTL_NO_GETTEXT_MACRO
#ifndef _
# define _(s) pxGetTranslation(_T(s))
#define _(s) pxGetTranslation(_T(s))
#endif
#ifndef _t
# define _t(s) pxGetTranslation(_T(s))
#define _t(s) pxGetTranslation(_T(s))
#endif
#ifndef _d
# define _d(s) pxGetTranslation(_T(s))
#define _d(s) pxGetTranslation(_T(s))
#endif
// pxL / pxLt / pxDt -- macros provided for tagging translation strings, without actually running
@ -167,15 +191,15 @@ public:
// debug/devel specific translations.
//
#ifndef pxL
# define pxL(a) wxT(a)
#define pxL(a) wxT(a)
#endif
#ifndef pxLt
# define pxLt(a) wxT(a)
#define pxLt(a) wxT(a)
#endif
#ifndef pxDt
# define pxDt(a) wxT(a)
#define pxDt(a) wxT(a)
#endif
@ -193,8 +217,8 @@ public:
#endif
#include <stdexcept>
#include <cstring> // string.h under c++
#include <cstdio> // stdio.h under c++
#include <cstring> // string.h under c++
#include <cstdio> // stdio.h under c++
#include <cstdlib>
#include <vector>
#include <list>
@ -207,42 +231,42 @@ public:
// --------------------------------------------------------------------------------------
// Handy Human-readable constants for common immediate values (_16kb -> _4gb)
static const sptr _1kb = 1024 * 1;
static const sptr _4kb = _1kb * 4;
static const sptr _16kb = _1kb * 16;
static const sptr _32kb = _1kb * 32;
static const sptr _64kb = _1kb * 64;
static const sptr _128kb = _1kb * 128;
static const sptr _256kb = _1kb * 256;
static const sptr _1kb = 1024 * 1;
static const sptr _4kb = _1kb * 4;
static const sptr _16kb = _1kb * 16;
static const sptr _32kb = _1kb * 32;
static const sptr _64kb = _1kb * 64;
static const sptr _128kb = _1kb * 128;
static const sptr _256kb = _1kb * 256;
static const s64 _1mb = 1024 * 1024;
static const s64 _8mb = _1mb * 8;
static const s64 _16mb = _1mb * 16;
static const s64 _32mb = _1mb * 32;
static const s64 _64mb = _1mb * 64;
static const s64 _256mb = _1mb * 256;
static const s64 _1gb = _1mb * 1024;
static const s64 _4gb = _1gb * 4;
static const s64 _1mb = 1024 * 1024;
static const s64 _8mb = _1mb * 8;
static const s64 _16mb = _1mb * 16;
static const s64 _32mb = _1mb * 32;
static const s64 _64mb = _1mb * 64;
static const s64 _256mb = _1mb * 256;
static const s64 _1gb = _1mb * 1024;
static const s64 _4gb = _1gb * 4;
// --------------------------------------------------------------------------------------
// pxE(msg) and pxEt(msg) [macros] => now same as _/_t/_d
// --------------------------------------------------------------------------------------
#define pxE(english) pxExpandMsg( (english) )
#define pxE(english) pxExpandMsg((english))
// For use with tertiary translations (low priority).
#define pxEt(english) pxExpandMsg( (english) )
#define pxEt(english) pxExpandMsg((english))
// For use with Dev/debug build translations (low priority).
#define pxE_dev(english) pxExpandMsg( (english) )
#define pxE_dev(english) pxExpandMsg((english))
extern const wxChar* __fastcall pxExpandMsg( const wxChar* englishContent );
extern const wxChar* __fastcall pxGetTranslation( const wxChar* message );
extern bool pxIsEnglish( int id );
extern const wxChar *__fastcall pxExpandMsg(const wxChar *englishContent);
extern const wxChar *__fastcall pxGetTranslation(const wxChar *message);
extern bool pxIsEnglish(int id);
extern wxString fromUTF8( const char* src );
extern wxString fromAscii( const char* src );
extern wxString fromUTF8(const char *src);
extern wxString fromAscii(const char *src);
#include "Utilities/Assertions.h"

View File

@ -25,8 +25,8 @@
class IEmbeddedImage
{
public:
virtual const wxImage& Get()=0;
virtual wxImage Scale( int width, int height )=0;
virtual const wxImage &Get() = 0;
virtual wxImage Scale(int width, int height) = 0;
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -38,85 +38,83 @@ public:
// Note: Get() only loads the image once. All subsequent calls to Get will use the
// previously loaded image data.
//
template< typename ImageType >
template <typename ImageType>
class EmbeddedImage : public IEmbeddedImage
{
protected:
wxImage m_Image;
const wxSize m_ResampleTo;
wxImage m_Image;
const wxSize m_ResampleTo;
protected:
// ------------------------------------------------------------------------
// Internal function used to ensure the image is loaded before returning the image
// handle (called from all methods that return an image handle).
//
void _loadImage()
{
if( !m_Image.Ok() )
{
wxMemoryInputStream joe( ImageType::Data, ImageType::Length );
m_Image.LoadFile( joe, ImageType::GetFormat() );
// ------------------------------------------------------------------------
// Internal function used to ensure the image is loaded before returning the image
// handle (called from all methods that return an image handle).
//
void _loadImage()
{
if (!m_Image.Ok()) {
wxMemoryInputStream joe(ImageType::Data, ImageType::Length);
m_Image.LoadFile(joe, ImageType::GetFormat());
if( m_ResampleTo.IsFullySpecified() && ( m_ResampleTo.GetWidth() != m_Image.GetWidth() || m_ResampleTo.GetHeight() != m_Image.GetHeight() ) )
m_Image.Rescale( m_ResampleTo.GetWidth(), m_ResampleTo.GetHeight(), wxIMAGE_QUALITY_HIGH );
}
}
if (m_ResampleTo.IsFullySpecified() && (m_ResampleTo.GetWidth() != m_Image.GetWidth() || m_ResampleTo.GetHeight() != m_Image.GetHeight()))
m_Image.Rescale(m_ResampleTo.GetWidth(), m_ResampleTo.GetHeight(), wxIMAGE_QUALITY_HIGH);
}
}
public:
EmbeddedImage() :
m_Image()
, m_ResampleTo( wxDefaultSize )
{
}
EmbeddedImage()
: m_Image()
, m_ResampleTo(wxDefaultSize)
{
}
// ------------------------------------------------------------------------
// Constructor for creating an embedded image that gets resampled to the specified size when
// loaded.
//
// Implementation Note: This function uses wxWidgets ResamplBox method to resize the image.
// wxWidgets ResampleBicubic appears to be buggy and produces fairly poor results when down-
// sampling images (basically resembles a pixel resize). ResampleBox produces much cleaner
// results.
//
EmbeddedImage( int newWidth, int newHeight ) :
m_Image()
, m_ResampleTo( newWidth, newHeight )
{
}
// ------------------------------------------------------------------------
// Constructor for creating an embedded image that gets resampled to the specified size when
// loaded.
//
// Implementation Note: This function uses wxWidgets ResamplBox method to resize the image.
// wxWidgets ResampleBicubic appears to be buggy and produces fairly poor results when down-
// sampling images (basically resembles a pixel resize). ResampleBox produces much cleaner
// results.
//
EmbeddedImage(int newWidth, int newHeight)
: m_Image()
, m_ResampleTo(newWidth, newHeight)
{
}
// ------------------------------------------------------------------------
// Loads and retrieves the embedded image. The embedded image is only loaded from its em-
// bedded format once. Any subsequent calls to Get(), Rescale(), or Resample() will use
// the pre-loaded copy. Translation: the png/jpeg decoding overhead happens only once,
// and only happens when the image is actually fetched. Simply creating an instance
// of an EmbeddedImage object uses no excess memory nor cpu overhead. :)
//
const wxImage& Get()
{
_loadImage();
return m_Image;
}
// ------------------------------------------------------------------------
// Loads and retrieves the embedded image. The embedded image is only loaded from its em-
// bedded format once. Any subsequent calls to Get(), Rescale(), or Resample() will use
// the pre-loaded copy. Translation: the png/jpeg decoding overhead happens only once,
// and only happens when the image is actually fetched. Simply creating an instance
// of an EmbeddedImage object uses no excess memory nor cpu overhead. :)
//
const wxImage &Get()
{
_loadImage();
return m_Image;
}
wxIcon GetIcon()
{
wxIcon retval;
retval.CopyFromBitmap( Get() );
return retval;
}
wxIcon GetIcon()
{
wxIcon retval;
retval.CopyFromBitmap(Get());
return retval;
}
// ------------------------------------------------------------------------
// Performs a pixel resize of the loaded image and returns a new image handle (EmbeddedImage
// is left unmodified).
//
// ------------------------------------------------------------------------
// Performs a pixel resize of the loaded image and returns a new image handle (EmbeddedImage
// is left unmodified).
//
wxImage Scale( int width, int height )
{
_loadImage();
// Not strictly necessary - wxWidgets does the dimensions check anyway.
if( width != m_Image.GetWidth() || height != m_Image.GetHeight() )
return m_Image.Scale( width, height, wxIMAGE_QUALITY_HIGH );
else
return m_Image;
}
wxImage Scale(int width, int height)
{
_loadImage();
// Not strictly necessary - wxWidgets does the dimensions check anyway.
if (width != m_Image.GetWidth() || height != m_Image.GetHeight())
return m_Image.Scale(width, height, wxIMAGE_QUALITY_HIGH);
else
return m_Image;
}
};

View File

@ -22,56 +22,58 @@
// EventSource< template EvtType >
// --------------------------------------------------------------------------------------
template< typename ListenerType >
template <typename ListenerType>
class EventSource
{
public:
typedef typename ListenerType::EvtParams EvtParams;
typedef typename std::list< ListenerType* > ListenerList;
typedef typename ListenerList::iterator ListenerIterator;
typedef typename ListenerType::EvtParams EvtParams;
typedef typename std::list<ListenerType *> ListenerList;
typedef typename ListenerList::iterator ListenerIterator;
protected:
typedef typename ListenerList::const_iterator ConstIterator;
typedef typename ListenerList::const_iterator ConstIterator;
ListenerList m_listeners;
ListenerList m_listeners;
// This is a cached copy of the listener list used to handle standard dispatching, which
// allows for self-modification of the EventSource's listener list by the listeners.
// Translation: The dispatcher uses this copy instead, to avoid iterator invalidation.
ListenerList m_cache_copy;
bool m_cache_valid;
// This is a cached copy of the listener list used to handle standard dispatching, which
// allows for self-modification of the EventSource's listener list by the listeners.
// Translation: The dispatcher uses this copy instead, to avoid iterator invalidation.
ListenerList m_cache_copy;
bool m_cache_valid;
Threading::Mutex m_listeners_lock;
Threading::Mutex m_listeners_lock;
public:
EventSource()
{
m_cache_valid = false;
}
EventSource()
{
m_cache_valid = false;
}
virtual ~EventSource() throw() {}
virtual ~EventSource() throw() {}
virtual ListenerIterator Add( ListenerType& listener );
virtual void Remove( ListenerType& listener );
virtual void Remove( const ListenerIterator& listenerHandle );
virtual ListenerIterator Add(ListenerType &listener);
virtual void Remove(ListenerType &listener);
virtual void Remove(const ListenerIterator &listenerHandle);
void Add( ListenerType* listener )
{
if( listener == NULL ) return;
Add( *listener );
}
void Add(ListenerType *listener)
{
if (listener == NULL)
return;
Add(*listener);
}
void Remove( ListenerType* listener )
{
if( listener == NULL ) return;
Remove( *listener );
}
void Remove(ListenerType *listener)
{
if (listener == NULL)
return;
Remove(*listener);
}
void Dispatch( const EvtParams& params );
void Dispatch(const EvtParams &params);
protected:
virtual ListenerIterator _AddFast_without_lock( ListenerType& listener );
virtual void _DispatchRaw( ListenerIterator iter, const ListenerIterator& iend, const EvtParams& params );
virtual ListenerIterator _AddFast_without_lock(ListenerType &listener);
virtual void _DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const EvtParams &params);
};
// --------------------------------------------------------------------------------------
@ -80,13 +82,13 @@ protected:
// This class is used as a base interface for EventListeners. It allows the listeners to do
// customized dispatching of several event types into "user friendly" function overrides.
//
template< typename EvtParams >
template <typename EvtParams>
class IEventDispatcher
{
protected:
IEventDispatcher() {}
IEventDispatcher() {}
public:
virtual ~IEventDispatcher() throw() {}
virtual void DispatchEvent( const EvtParams& params )=0;
virtual ~IEventDispatcher() throw() {}
virtual void DispatchEvent(const EvtParams &params) = 0;
};

View File

@ -19,88 +19,80 @@
using Threading::ScopedLock;
template< typename ListenerType >
typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::Add( ListenerType& listener )
template <typename ListenerType>
typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::Add(ListenerType &listener)
{
ScopedLock locker( m_listeners_lock );
ScopedLock locker(m_listeners_lock);
// Check for duplicates before adding the event.
if( IsDebugBuild )
{
ListenerIterator iter = m_listeners.begin();
while( iter != m_listeners.end() )
{
if( (*iter) == &listener ) return iter;
++iter;
}
}
return _AddFast_without_lock( listener );
// Check for duplicates before adding the event.
if (IsDebugBuild) {
ListenerIterator iter = m_listeners.begin();
while (iter != m_listeners.end()) {
if ((*iter) == &listener)
return iter;
++iter;
}
}
return _AddFast_without_lock(listener);
}
template< typename ListenerType >
void EventSource<ListenerType>::Remove( ListenerType& listener )
template <typename ListenerType>
void EventSource<ListenerType>::Remove(ListenerType &listener)
{
ScopedLock locker( m_listeners_lock );
m_cache_valid = false;
m_listeners.remove( &listener );
ScopedLock locker(m_listeners_lock);
m_cache_valid = false;
m_listeners.remove(&listener);
}
template< typename ListenerType >
void EventSource<ListenerType>::Remove( const ListenerIterator& listenerHandle )
template <typename ListenerType>
void EventSource<ListenerType>::Remove(const ListenerIterator &listenerHandle)
{
ScopedLock locker( m_listeners_lock );
m_cache_valid = false;
m_listeners.erase( listenerHandle );
ScopedLock locker(m_listeners_lock);
m_cache_valid = false;
m_listeners.erase(listenerHandle);
}
template< typename ListenerType >
typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::_AddFast_without_lock( ListenerType& listener )
template <typename ListenerType>
typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::_AddFast_without_lock(ListenerType &listener)
{
m_cache_valid = false;
m_listeners.push_front( &listener );
return m_listeners.begin();
m_cache_valid = false;
m_listeners.push_front(&listener);
return m_listeners.begin();
}
template< typename ListenerType >
__fi void EventSource<ListenerType>::_DispatchRaw( ListenerIterator iter, const ListenerIterator& iend, const EvtParams& evtparams )
template <typename ListenerType>
__fi void EventSource<ListenerType>::_DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const EvtParams &evtparams)
{
while( iter != iend )
{
try {
(*iter)->DispatchEvent( evtparams );
}
catch( Exception::RuntimeError& ex )
{
if( IsDevBuild ) {
pxFailDev( L"Ignoring runtime error thrown from event listener (event listeners should not throw exceptions!): " + ex.FormatDiagnosticMessage() );
}
else {
Console.Error( L"Ignoring runtime error thrown from event listener: " + ex.FormatDiagnosticMessage() );
}
}
catch( BaseException& ex )
{
if( IsDevBuild )
{
ex.DiagMsg() = L"Non-runtime BaseException thrown from event listener .. " + ex.DiagMsg();
throw;
}
Console.Error( L"Ignoring non-runtime BaseException thrown from event listener: " + ex.FormatDiagnosticMessage() );
}
++iter;
}
while (iter != iend) {
try {
(*iter)->DispatchEvent(evtparams);
} catch (Exception::RuntimeError &ex) {
if (IsDevBuild) {
pxFailDev(L"Ignoring runtime error thrown from event listener (event listeners should not throw exceptions!): " + ex.FormatDiagnosticMessage());
} else {
Console.Error(L"Ignoring runtime error thrown from event listener: " + ex.FormatDiagnosticMessage());
}
} catch (BaseException &ex) {
if (IsDevBuild) {
ex.DiagMsg() = L"Non-runtime BaseException thrown from event listener .. " + ex.DiagMsg();
throw;
}
Console.Error(L"Ignoring non-runtime BaseException thrown from event listener: " + ex.FormatDiagnosticMessage());
}
++iter;
}
}
template< typename ListenerType >
void EventSource<ListenerType>::Dispatch( const EvtParams& evtparams )
template <typename ListenerType>
void EventSource<ListenerType>::Dispatch(const EvtParams &evtparams)
{
if( !m_cache_valid )
{
m_cache_copy = m_listeners;
m_cache_valid = true;
}
if (!m_cache_valid) {
m_cache_copy = m_listeners;
m_cache_valid = true;
}
if( m_cache_copy.empty() ) return;
_DispatchRaw( m_cache_copy.begin(), m_cache_copy.end(), evtparams );
if (m_cache_copy.empty())
return;
_DispatchRaw(m_cache_copy.begin(), m_cache_copy.end(), evtparams);
}

View File

@ -30,112 +30,113 @@ void pxTrap();
// friendly error log in their wake.
//
// Note: Console can also fire an Exception::OutOfMemory
#define __DESTRUCTOR_CATCHALL( funcname ) \
catch( BaseException& ex ) \
{ \
try { \
Console.Error( "Unhandled BaseException in %s (ignored!):", funcname ); \
Console.Error( ex.FormatDiagnosticMessage() ); \
} catch (...) { \
fprintf(stderr, "ERROR: (out of memory?)\n"); \
} \
} \
catch( std::exception& ex ) \
{ \
try { \
Console.Error( "Unhandled std::exception in %s (ignored!):", funcname ); \
Console.Error( ex.what() ); \
} catch (...) { \
fprintf(stderr, "ERROR: (out of memory?)\n"); \
} \
} \
catch(...) { \
/* Unreachable code */ \
}
#define __DESTRUCTOR_CATCHALL(funcname) \
catch (BaseException & ex) \
{ \
try { \
Console.Error("Unhandled BaseException in %s (ignored!):", funcname); \
Console.Error(ex.FormatDiagnosticMessage()); \
} catch (...) { \
fprintf(stderr, "ERROR: (out of memory?)\n"); \
} \
} \
catch (std::exception & ex) \
{ \
try { \
Console.Error("Unhandled std::exception in %s (ignored!):", funcname); \
Console.Error(ex.what()); \
} catch (...) { \
fprintf(stderr, "ERROR: (out of memory?)\n"); \
} \
} \
catch (...) \
{ \
/* Unreachable code */ \
}
#define DESTRUCTOR_CATCHALL __DESTRUCTOR_CATCHALL( __pxFUNCTION__ )
#define DESTRUCTOR_CATCHALL __DESTRUCTOR_CATCHALL(__pxFUNCTION__)
namespace Exception
{
int MakeNewType();
BaseException* FromErrno( const wxString& streamname, int errcode );
int MakeNewType();
BaseException *FromErrno(const wxString &streamname, int errcode);
// --------------------------------------------------------------------------------------
// BaseException
// --------------------------------------------------------------------------------------
// std::exception sucks, and isn't entirely cross-platform reliable in its implementation,
// so I made a replacement. The internal messages are non-const, which means that a
// catch clause can optionally modify them and then re-throw to a top-level handler.
//
// Note, this class is "abstract" which means you shouldn't use it directly like, ever.
// Use Exception::RuntimeError instead for generic exceptions.
//
// Because exceptions are the (only!) really useful example of multiple inheritance,
// this class has only a trivial constructor, and must be manually initialized using
// InitBaseEx() or by individual member assignments. This is because C++ multiple inheritence
// is, by design, a lot of fail, especially when class initializers are mixed in.
//
// [TODO] : Add an InnerException component, and Clone() facility.
//
class BaseException
{
protected:
wxString m_message_diag; // (untranslated) a "detailed" message of what disastrous thing has occurred!
wxString m_message_user; // (translated) a "detailed" message of what disastrous thing has occurred!
// --------------------------------------------------------------------------------------
// BaseException
// --------------------------------------------------------------------------------------
// std::exception sucks, and isn't entirely cross-platform reliable in its implementation,
// so I made a replacement. The internal messages are non-const, which means that a
// catch clause can optionally modify them and then re-throw to a top-level handler.
//
// Note, this class is "abstract" which means you shouldn't use it directly like, ever.
// Use Exception::RuntimeError instead for generic exceptions.
//
// Because exceptions are the (only!) really useful example of multiple inheritance,
// this class has only a trivial constructor, and must be manually initialized using
// InitBaseEx() or by individual member assignments. This is because C++ multiple inheritence
// is, by design, a lot of fail, especially when class initializers are mixed in.
//
// [TODO] : Add an InnerException component, and Clone() facility.
//
class BaseException
{
protected:
wxString m_message_diag; // (untranslated) a "detailed" message of what disastrous thing has occurred!
wxString m_message_user; // (translated) a "detailed" message of what disastrous thing has occurred!
public:
virtual ~BaseException() throw()=0; // the =0; syntax forces this class into "abstract" mode.
public:
virtual ~BaseException() throw() = 0; // the =0; syntax forces this class into "abstract" mode.
const wxString& DiagMsg() const { return m_message_diag; }
const wxString& UserMsg() const { return m_message_user; }
const wxString &DiagMsg() const { return m_message_diag; }
const wxString &UserMsg() const { return m_message_user; }
wxString& DiagMsg() { return m_message_diag; }
wxString& UserMsg() { return m_message_user; }
wxString &DiagMsg() { return m_message_diag; }
wxString &UserMsg() { return m_message_user; }
BaseException& SetBothMsgs( const wxChar* msg_diag );
BaseException& SetDiagMsg( const wxString& msg_diag );
BaseException& SetUserMsg( const wxString& msg_user );
BaseException &SetBothMsgs(const wxChar *msg_diag);
BaseException &SetDiagMsg(const wxString &msg_diag);
BaseException &SetUserMsg(const wxString &msg_user);
// Returns a message suitable for diagnostic / logging purposes.
// This message is always in English, and includes a full stack trace.
virtual wxString FormatDiagnosticMessage() const;
// Returns a message suitable for diagnostic / logging purposes.
// This message is always in English, and includes a full stack trace.
virtual wxString FormatDiagnosticMessage() const;
// Returns a message suitable for end-user display.
// This message is usually meant for display in a user popup or such.
virtual wxString FormatDisplayMessage() const;
// Returns a message suitable for end-user display.
// This message is usually meant for display in a user popup or such.
virtual wxString FormatDisplayMessage() const;
virtual void Rethrow() const=0;
virtual BaseException* Clone() const=0;
};
virtual void Rethrow() const = 0;
virtual BaseException *Clone() const = 0;
};
typedef std::unique_ptr<BaseException> ScopedExcept;
typedef std::unique_ptr<BaseException> ScopedExcept;
// --------------------------------------------------------------------------------------
// Ps2Generic Exception
// --------------------------------------------------------------------------------------
// This class is used as a base exception for things tossed by PS2 cpus (EE, IOP, etc).
//
// Implementation note: does not derive from BaseException, so that we can use different
// catch block hierarchies to handle them (if needed).
//
// Translation Note: Currently these exceptions are never translated. English/diagnostic
// format only. :)
//
class Ps2Generic
{
protected:
wxString m_message; // a "detailed" message of what disastrous thing has occurred!
// --------------------------------------------------------------------------------------
// Ps2Generic Exception
// --------------------------------------------------------------------------------------
// This class is used as a base exception for things tossed by PS2 cpus (EE, IOP, etc).
//
// Implementation note: does not derive from BaseException, so that we can use different
// catch block hierarchies to handle them (if needed).
//
// Translation Note: Currently these exceptions are never translated. English/diagnostic
// format only. :)
//
class Ps2Generic
{
protected:
wxString m_message; // a "detailed" message of what disastrous thing has occurred!
public:
virtual ~Ps2Generic() throw() {}
public:
virtual ~Ps2Generic() throw() {}
virtual u32 GetPc() const=0;
virtual bool IsDelaySlot() const=0;
virtual wxString& Message() { return m_message; }
virtual u32 GetPc() const = 0;
virtual bool IsDelaySlot() const = 0;
virtual wxString &Message() { return m_message; }
virtual void Rethrow() const=0;
virtual Ps2Generic* Clone() const=0;
};
virtual void Rethrow() const = 0;
virtual Ps2Generic *Clone() const = 0;
};
// Some helper macros for defining the standard constructors of internationalized constructors
// Parameters:
@ -151,217 +152,239 @@ namespace Exception
//
// (update: web searches indicate it's MSVC specific -- happens in 2008, not sure about 2010).
//
#define DEFINE_EXCEPTION_COPYTORS( classname, parent ) \
private: \
typedef parent _parent; \
public: \
virtual ~classname() throw() {} \
virtual void Rethrow() const { throw *this; } \
virtual classname* Clone() const { return new classname( *this ); }
#define DEFINE_EXCEPTION_COPYTORS(classname, parent) \
private: \
typedef parent _parent; \
\
public: \
virtual ~classname() throw() {} \
virtual void Rethrow() const { throw * this; } \
virtual classname *Clone() const { return new classname(*this); }
#define DEFINE_EXCEPTION_MESSAGES( classname ) \
public: \
classname& SetBothMsgs( const wxChar* msg_diag ) { BaseException::SetBothMsgs(msg_diag); return *this; } \
classname& SetDiagMsg( const wxString& msg_diag ) { m_message_diag = msg_diag; return *this; } \
classname& SetUserMsg( const wxString& msg_user ) { m_message_user = msg_user; return *this; }
#define DEFINE_EXCEPTION_MESSAGES(classname) \
public: \
classname &SetBothMsgs(const wxChar *msg_diag) \
{ \
BaseException::SetBothMsgs(msg_diag); \
return *this; \
} \
classname &SetDiagMsg(const wxString &msg_diag) \
{ \
m_message_diag = msg_diag; \
return *this; \
} \
classname &SetUserMsg(const wxString &msg_user) \
{ \
m_message_user = msg_user; \
return *this; \
}
#define DEFINE_RUNTIME_EXCEPTION( classname, parent, message ) \
DEFINE_EXCEPTION_COPYTORS( classname, parent ) \
classname() { SetDiagMsg(message); } \
DEFINE_EXCEPTION_MESSAGES( classname )
// ---------------------------------------------------------------------------------------
// RuntimeError - Generalized Exceptions with Recoverable Traits!
// ---------------------------------------------------------------------------------------
#define DEFINE_RUNTIME_EXCEPTION(classname, parent, message) \
DEFINE_EXCEPTION_COPYTORS(classname, parent) \
classname() { SetDiagMsg(message); } \
DEFINE_EXCEPTION_MESSAGES(classname)
class RuntimeError : public BaseException
{
DEFINE_EXCEPTION_COPYTORS( RuntimeError, BaseException )
DEFINE_EXCEPTION_MESSAGES( RuntimeError )
public:
bool IsSilent;
// ---------------------------------------------------------------------------------------
// RuntimeError - Generalized Exceptions with Recoverable Traits!
// ---------------------------------------------------------------------------------------
RuntimeError() { IsSilent = false; }
RuntimeError( const std::runtime_error& ex, const wxString& prefix=wxEmptyString );
RuntimeError( const std::exception& ex, const wxString& prefix=wxEmptyString );
};
class RuntimeError : public BaseException
{
DEFINE_EXCEPTION_COPYTORS(RuntimeError, BaseException)
DEFINE_EXCEPTION_MESSAGES(RuntimeError)
// --------------------------------------------------------------------------------------
// CancelAppEvent - Exception for canceling an event in a non-verbose fashion
// --------------------------------------------------------------------------------------
// Typically the PCSX2 interface issues popup dialogs for runtime errors. This exception
// instead issues a "silent" cancelation that is handled by the app gracefully (generates
// log, and resumes messages queue processing).
//
// I chose to have this exception derive from RuntimeError, since if one is thrown from outside
// an App message loop we'll still want it to be handled in a reasonably graceful manner.
class CancelEvent : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION( CancelEvent, RuntimeError, pxLt("No reason given.") )
public:
bool IsSilent;
public:
explicit CancelEvent( const wxString& logmsg )
{
m_message_diag = logmsg;
// overridden message formatters only use the diagnostic version...
}
RuntimeError() { IsSilent = false; }
RuntimeError(const std::runtime_error &ex, const wxString &prefix = wxEmptyString);
RuntimeError(const std::exception &ex, const wxString &prefix = wxEmptyString);
};
virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const;
};
// --------------------------------------------------------------------------------------
// CancelAppEvent - Exception for canceling an event in a non-verbose fashion
// --------------------------------------------------------------------------------------
// Typically the PCSX2 interface issues popup dialogs for runtime errors. This exception
// instead issues a "silent" cancelation that is handled by the app gracefully (generates
// log, and resumes messages queue processing).
//
// I chose to have this exception derive from RuntimeError, since if one is thrown from outside
// an App message loop we'll still want it to be handled in a reasonably graceful manner.
class CancelEvent : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION(CancelEvent, RuntimeError, pxLt("No reason given."))
// ---------------------------------------------------------------------------------------
// OutOfMemory
// ---------------------------------------------------------------------------------------
// This exception has a custom-formatted Diagnostic string. The parameter give when constructing
// the exception is a block/alloc name, which is used as a formatting parameter in the diagnostic
// output. The default diagnostic message is "Out of memory exception, while allocating the %s."
// where %s is filled in with the block name.
//
// The user string is not custom-formatted, and should contain *NO* %s tags.
//
class OutOfMemory : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION( OutOfMemory, RuntimeError, wxEmptyString )
public:
explicit CancelEvent(const wxString &logmsg)
{
m_message_diag = logmsg;
// overridden message formatters only use the diagnostic version...
}
public:
wxString AllocDescription;
virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const;
};
public:
OutOfMemory( const wxString& allocdesc );
// ---------------------------------------------------------------------------------------
// OutOfMemory
// ---------------------------------------------------------------------------------------
// This exception has a custom-formatted Diagnostic string. The parameter give when constructing
// the exception is a block/alloc name, which is used as a formatting parameter in the diagnostic
// output. The default diagnostic message is "Out of memory exception, while allocating the %s."
// where %s is filled in with the block name.
//
// The user string is not custom-formatted, and should contain *NO* %s tags.
//
class OutOfMemory : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION(OutOfMemory, RuntimeError, wxEmptyString)
virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const;
};
public:
wxString AllocDescription;
class ParseError : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION( ParseError, RuntimeError, pxL("Parse error") );
};
public:
OutOfMemory(const wxString &allocdesc);
// ---------------------------------------------------------------------------------------
// Hardware/OS Exceptions:
// HardwareDeficiency / VirtualMemoryMapConflict
// ---------------------------------------------------------------------------------------
virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const;
};
// This exception is a specific type of OutOfMemory error that isn't "really" an out of
// memory error. More likely it's caused by a plugin or driver reserving a range of memory
// we'd really like to have access to.
class VirtualMemoryMapConflict : public OutOfMemory
{
DEFINE_RUNTIME_EXCEPTION( VirtualMemoryMapConflict, OutOfMemory, wxEmptyString )
class ParseError : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION(ParseError, RuntimeError, pxL("Parse error"));
};
VirtualMemoryMapConflict( const wxString& allocdesc );
// ---------------------------------------------------------------------------------------
// Hardware/OS Exceptions:
// HardwareDeficiency / VirtualMemoryMapConflict
// ---------------------------------------------------------------------------------------
virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const;
};
// This exception is a specific type of OutOfMemory error that isn't "really" an out of
// memory error. More likely it's caused by a plugin or driver reserving a range of memory
// we'd really like to have access to.
class VirtualMemoryMapConflict : public OutOfMemory
{
DEFINE_RUNTIME_EXCEPTION(VirtualMemoryMapConflict, OutOfMemory, wxEmptyString)
class HardwareDeficiency : public RuntimeError
{
public:
DEFINE_RUNTIME_EXCEPTION( HardwareDeficiency, RuntimeError, pxL("Your machine's hardware is incapable of running PCSX2. Sorry dood.") );
};
VirtualMemoryMapConflict(const wxString &allocdesc);
// ---------------------------------------------------------------------------------------
// Streaming (file) Exceptions:
// Stream / BadStream / CannotCreateStream / FileNotFound / AccessDenied / EndOfStream
// ---------------------------------------------------------------------------------------
virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const;
};
#define DEFINE_STREAM_EXCEPTION_ACCESSORS( classname ) \
virtual classname& SetStreamName( const wxString& name ) { StreamName = name; return *this; } \
virtual classname& SetStreamName( const char* name ) { StreamName = fromUTF8(name); return *this; }
class HardwareDeficiency : public RuntimeError
{
public:
DEFINE_RUNTIME_EXCEPTION(HardwareDeficiency, RuntimeError, pxL("Your machine's hardware is incapable of running PCSX2. Sorry dood."));
};
#define DEFINE_STREAM_EXCEPTION( classname, parent ) \
DEFINE_RUNTIME_EXCEPTION( classname, parent, wxEmptyString ) \
classname( const wxString& filename ) { \
StreamName = filename; \
} \
DEFINE_STREAM_EXCEPTION_ACCESSORS( classname )
// A generic base error class for bad streams -- corrupted data, sudden closures, loss of
// connection, or anything else that would indicate a failure to open a stream or read the
// data after the stream was successfully opened.
//
class BadStream : public RuntimeError
{
DEFINE_STREAM_EXCEPTION( BadStream, RuntimeError )
// ---------------------------------------------------------------------------------------
// Streaming (file) Exceptions:
// Stream / BadStream / CannotCreateStream / FileNotFound / AccessDenied / EndOfStream
// ---------------------------------------------------------------------------------------
public:
wxString StreamName; // name of the stream (if applicable)
#define DEFINE_STREAM_EXCEPTION_ACCESSORS(classname) \
virtual classname &SetStreamName(const wxString &name) \
{ \
StreamName = name; \
return *this; \
} \
virtual classname &SetStreamName(const char *name) \
{ \
StreamName = fromUTF8(name); \
return *this; \
}
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
#define DEFINE_STREAM_EXCEPTION(classname, parent) \
DEFINE_RUNTIME_EXCEPTION(classname, parent, wxEmptyString) \
classname(const wxString &filename) \
{ \
StreamName = filename; \
} \
DEFINE_STREAM_EXCEPTION_ACCESSORS(classname)
protected:
void _formatDiagMsg( FastFormatUnicode& dest ) const;
void _formatUserMsg( FastFormatUnicode& dest ) const;
};
// A generic base error class for bad streams -- corrupted data, sudden closures, loss of
// connection, or anything else that would indicate a failure to open a stream or read the
// data after the stream was successfully opened.
//
class BadStream : public RuntimeError
{
DEFINE_STREAM_EXCEPTION(BadStream, RuntimeError)
// A generic exception for odd-ball stream creation errors.
//
class CannotCreateStream : public BadStream
{
DEFINE_STREAM_EXCEPTION( CannotCreateStream, BadStream )
public:
wxString StreamName; // name of the stream (if applicable)
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
};
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
// Exception thrown when an attempt to open a non-existent file is made.
// (this exception can also mean file permissions are invalid)
//
class FileNotFound : public CannotCreateStream
{
public:
DEFINE_STREAM_EXCEPTION( FileNotFound, CannotCreateStream )
protected:
void _formatDiagMsg(FastFormatUnicode &dest) const;
void _formatUserMsg(FastFormatUnicode &dest) const;
};
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
};
// A generic exception for odd-ball stream creation errors.
//
class CannotCreateStream : public BadStream
{
DEFINE_STREAM_EXCEPTION(CannotCreateStream, BadStream)
class AccessDenied : public CannotCreateStream
{
public:
DEFINE_STREAM_EXCEPTION( AccessDenied, CannotCreateStream )
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
};
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
};
// Exception thrown when an attempt to open a non-existent file is made.
// (this exception can also mean file permissions are invalid)
//
class FileNotFound : public CannotCreateStream
{
public:
DEFINE_STREAM_EXCEPTION(FileNotFound, CannotCreateStream)
// EndOfStream can be used either as an error, or used just as a shortcut for manual
// feof checks.
//
class EndOfStream : public BadStream
{
public:
DEFINE_STREAM_EXCEPTION( EndOfStream, BadStream )
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
};
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
};
class AccessDenied : public CannotCreateStream
{
public:
DEFINE_STREAM_EXCEPTION(AccessDenied, CannotCreateStream)
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
};
// EndOfStream can be used either as an error, or used just as a shortcut for manual
// feof checks.
//
class EndOfStream : public BadStream
{
public:
DEFINE_STREAM_EXCEPTION(EndOfStream, BadStream)
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
};
#ifdef __WXMSW__
// --------------------------------------------------------------------------------------
// Exception::WinApiError
// --------------------------------------------------------------------------------------
class WinApiError : public RuntimeError
{
DEFINE_EXCEPTION_COPYTORS( WinApiError, RuntimeError )
DEFINE_EXCEPTION_MESSAGES( WinApiError )
// --------------------------------------------------------------------------------------
// Exception::WinApiError
// --------------------------------------------------------------------------------------
class WinApiError : public RuntimeError
{
DEFINE_EXCEPTION_COPYTORS(WinApiError, RuntimeError)
DEFINE_EXCEPTION_MESSAGES(WinApiError)
public:
int ErrorId;
public:
int ErrorId;
public:
WinApiError();
public:
WinApiError();
wxString GetMsgFromWindows() const;
virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const;
};
wxString GetMsgFromWindows() const;
virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const;
};
#endif
}

View File

@ -17,59 +17,59 @@
#include "Dependencies.h"
template< int Precision >
template <int Precision>
struct FixedInt
{
s32 Raw;
s32 Raw;
FixedInt();
FixedInt( int signedval );
FixedInt( double doubval );
FixedInt( float floval );
FixedInt();
FixedInt(int signedval);
FixedInt(double doubval);
FixedInt(float floval);
bool operator ==( const FixedInt<Precision>& right ) const { return Raw == right.Raw; }
bool operator !=( const FixedInt<Precision>& right ) const { return Raw != right.Raw; }
bool operator==(const FixedInt<Precision> &right) const { return Raw == right.Raw; }
bool operator!=(const FixedInt<Precision> &right) const { return Raw != right.Raw; }
bool operator>( const FixedInt<Precision>& right ) const { return Raw > right.Raw; };
bool operator>=( const FixedInt<Precision>& right ) const { return Raw >= right.Raw; };
bool operator<( const FixedInt<Precision>& right ) const { return Raw < right.Raw; };
bool operator<=( const FixedInt<Precision>& right ) const { return Raw <= right.Raw; };
bool operator>(const FixedInt<Precision> &right) const { return Raw > right.Raw; };
bool operator>=(const FixedInt<Precision> &right) const { return Raw >= right.Raw; };
bool operator<(const FixedInt<Precision> &right) const { return Raw < right.Raw; };
bool operator<=(const FixedInt<Precision> &right) const { return Raw <= right.Raw; };
FixedInt<Precision> operator+( const FixedInt<Precision>& right ) const;
FixedInt<Precision> operator-( const FixedInt<Precision>& right ) const;
FixedInt<Precision>& operator+=( const FixedInt<Precision>& right );
FixedInt<Precision>& operator-=( const FixedInt<Precision>& right );
FixedInt<Precision> operator+(const FixedInt<Precision> &right) const;
FixedInt<Precision> operator-(const FixedInt<Precision> &right) const;
FixedInt<Precision> &operator+=(const FixedInt<Precision> &right);
FixedInt<Precision> &operator-=(const FixedInt<Precision> &right);
FixedInt<Precision>& ConfineTo( const FixedInt<Precision>& low, const FixedInt<Precision>& high );
FixedInt<Precision> &ConfineTo(const FixedInt<Precision> &low, const FixedInt<Precision> &high);
FixedInt<Precision> operator*( const FixedInt<Precision>& right ) const;
FixedInt<Precision> operator/( const FixedInt<Precision>& right ) const;
FixedInt<Precision>& operator*=( const FixedInt<Precision>& right );
FixedInt<Precision>& operator/=( const FixedInt<Precision>& right );
FixedInt<Precision> operator*(const FixedInt<Precision> &right) const;
FixedInt<Precision> operator/(const FixedInt<Precision> &right) const;
FixedInt<Precision> &operator*=(const FixedInt<Precision> &right);
FixedInt<Precision> &operator/=(const FixedInt<Precision> &right);
static bool OverflowCheck( int signedval );
static bool OverflowCheck( double signedval );
static bool OverflowCheck(int signedval);
static bool OverflowCheck(double signedval);
int GetWhole() const;
int GetFraction() const;
int GetWhole() const;
int GetFraction() const;
FixedInt<Precision>& SetRaw( s32 rawsrc );
FixedInt<Precision>& Round();
FixedInt<Precision>& SetWhole( s32 wholepart );
FixedInt<Precision>& SetFraction( u32 fracpart );
FixedInt<Precision> &SetRaw(s32 rawsrc);
FixedInt<Precision> &Round();
FixedInt<Precision> &SetWhole(s32 wholepart);
FixedInt<Precision> &SetFraction(u32 fracpart);
wxString ToString() const;
wxString ToString( int fracDigits ) const;
wxString ToString() const;
wxString ToString(int fracDigits) const;
double ToDouble() const;
float ToFloat() const;
int ToIntTruncated() const;
int ToIntRounded() const;
double ToDouble() const;
float ToFloat() const;
int ToIntTruncated() const;
int ToIntRounded() const;
static bool TryFromString( FixedInt<Precision>& dest, const wxString& parseFrom );
static FixedInt<Precision> FromString( const wxString& parseFrom, const FixedInt<Precision>& defval );
static FixedInt<Precision> FromString( const wxString parseFrom );
static bool TryFromString(FixedInt<Precision> &dest, const wxString &parseFrom);
static FixedInt<Precision> FromString(const wxString &parseFrom, const FixedInt<Precision> &defval);
static FixedInt<Precision> FromString(const wxString parseFrom);
};
typedef FixedInt<256> Fixed256;
typedef FixedInt<100> Fixed100;
typedef FixedInt<256> Fixed256;
typedef FixedInt<100> Fixed100;

View File

@ -16,226 +16,237 @@
#pragma once
#include "FixedPointTypes.h"
#include <cmath> // for pow!
#include <cmath> // for pow!
template< int Precision >
template <int Precision>
FixedInt<Precision>::FixedInt()
{
Raw = 0;
Raw = 0;
}
template< int Precision >
FixedInt<Precision>::FixedInt( int signedval )
template <int Precision>
FixedInt<Precision>::FixedInt(int signedval)
{
Raw = signedval * Precision;
Raw = signedval * Precision;
}
template< int Precision >
FixedInt<Precision>::FixedInt( double doubval )
template <int Precision>
FixedInt<Precision>::FixedInt(double doubval)
{
Raw = lround(doubval * (double)Precision);
Raw = lround(doubval * (double)Precision);
}
template< int Precision >
FixedInt<Precision>::FixedInt( float floval )
template <int Precision>
FixedInt<Precision>::FixedInt(float floval)
{
Raw = lroundf(floval * (float)Precision);
Raw = lroundf(floval * (float)Precision);
}
template< int Precision >
FixedInt<Precision> FixedInt<Precision>::operator+( const FixedInt<Precision>& right ) const
template <int Precision>
FixedInt<Precision> FixedInt<Precision>::operator+(const FixedInt<Precision> &right) const
{
return FixedInt<Precision>().SetRaw( Raw + right.Raw );
return FixedInt<Precision>().SetRaw(Raw + right.Raw);
}
template< int Precision >
FixedInt<Precision> FixedInt<Precision>::operator-( const FixedInt<Precision>& right ) const
template <int Precision>
FixedInt<Precision> FixedInt<Precision>::operator-(const FixedInt<Precision> &right) const
{
return FixedInt<Precision>().SetRaw( Raw + right.Raw );
return FixedInt<Precision>().SetRaw(Raw + right.Raw);
}
template< int Precision >
FixedInt<Precision>& FixedInt<Precision>::operator+=( const FixedInt<Precision>& right )
template <int Precision>
FixedInt<Precision> &FixedInt<Precision>::operator+=(const FixedInt<Precision> &right)
{
return SetRaw( Raw + right.Raw );
return SetRaw(Raw + right.Raw);
}
template< int Precision >
FixedInt<Precision>& FixedInt<Precision>::operator-=( const FixedInt<Precision>& right )
template <int Precision>
FixedInt<Precision> &FixedInt<Precision>::operator-=(const FixedInt<Precision> &right)
{
return SetRaw( Raw + right.Raw );
return SetRaw(Raw + right.Raw);
}
template< int Precision >
FixedInt<Precision>& FixedInt<Precision>::ConfineTo( const FixedInt<Precision>& low, const FixedInt<Precision>& high )
template <int Precision>
FixedInt<Precision> &FixedInt<Precision>::ConfineTo(const FixedInt<Precision> &low, const FixedInt<Precision> &high)
{
return SetRaw( std::min( std::max( Raw, low.Raw ), high.Raw ) );
return SetRaw(std::min(std::max(Raw, low.Raw), high.Raw));
}
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
// you'll need to use the Raw values directly.
template< int Precision >
FixedInt<Precision> FixedInt<Precision>::operator*( const FixedInt<Precision>& right ) const
template <int Precision>
FixedInt<Precision> FixedInt<Precision>::operator*(const FixedInt<Precision> &right) const
{
s64 mulres = (s64)Raw * right.Raw;
return FixedInt<Precision>().SetRaw( (s32)(mulres / Precision) );
s64 mulres = (s64)Raw * right.Raw;
return FixedInt<Precision>().SetRaw((s32)(mulres / Precision));
}
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
// you'll need to use the Raw values directly.
template< int Precision >
FixedInt<Precision> FixedInt<Precision>::operator/( const FixedInt<Precision>& right ) const
template <int Precision>
FixedInt<Precision> FixedInt<Precision>::operator/(const FixedInt<Precision> &right) const
{
s64 divres = Raw * Precision;
return FixedInt<Precision>().SetRaw( (s32)(divres / right.Raw) );
s64 divres = Raw * Precision;
return FixedInt<Precision>().SetRaw((s32)(divres / right.Raw));
}
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
// you'll need to use the Raw values directly.
template< int Precision >
FixedInt<Precision>& FixedInt<Precision>::operator*=( const FixedInt<Precision>& right )
template <int Precision>
FixedInt<Precision> &FixedInt<Precision>::operator*=(const FixedInt<Precision> &right)
{
s64 mulres = (s64)Raw * right.Raw;
return SetRaw( (s32)(mulres / Precision) );
s64 mulres = (s64)Raw * right.Raw;
return SetRaw((s32)(mulres / Precision));
}
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
// you'll need to use the Raw values directly.
template< int Precision >
FixedInt<Precision>& FixedInt<Precision>::operator/=( const FixedInt<Precision>& right )
template <int Precision>
FixedInt<Precision> &FixedInt<Precision>::operator/=(const FixedInt<Precision> &right)
{
s64 divres = Raw * Precision;
return SetRaw( (s32)(divres / right.Raw) );
s64 divres = Raw * Precision;
return SetRaw((s32)(divres / right.Raw));
}
// returns TRUE if the value overflows the legal integer range of this container.
template< int Precision >
bool FixedInt<Precision>::OverflowCheck( int signedval )
template <int Precision>
bool FixedInt<Precision>::OverflowCheck(int signedval)
{
return ( signedval >= (INT_MAX / Precision) );
return (signedval >= (INT_MAX / Precision));
}
// returns TRUE if the value overflows the legal integer range of this container.
template< int Precision >
bool FixedInt<Precision>::OverflowCheck( double signedval )
template <int Precision>
bool FixedInt<Precision>::OverflowCheck(double signedval)
{
return ( signedval >= (INT_MAX / Precision) );
return (signedval >= (INT_MAX / Precision));
}
template< int Precision > int FixedInt<Precision>::GetWhole() const { return Raw / Precision; }
template< int Precision > int FixedInt<Precision>::GetFraction() const { return Raw % Precision; }
template< int Precision >
FixedInt<Precision>& FixedInt<Precision>::SetRaw( s32 rawsrc )
template <int Precision>
int FixedInt<Precision>::GetWhole() const
{
Raw = rawsrc;
return *this;
return Raw / Precision;
}
template <int Precision>
int FixedInt<Precision>::GetFraction() const
{
return Raw % Precision;
}
template< int Precision >
FixedInt<Precision>& FixedInt<Precision>::Round()
template <int Precision>
FixedInt<Precision> &FixedInt<Precision>::SetRaw(s32 rawsrc)
{
Raw = ToIntRounded();
return *this;
Raw = rawsrc;
return *this;
}
template< int Precision >
FixedInt<Precision>& FixedInt<Precision>::SetWhole( s32 wholepart )
template <int Precision>
FixedInt<Precision> &FixedInt<Precision>::Round()
{
pxAssert( wholepart < (INT_MAX / Precision) );
Raw = GetFraction() + (wholepart * Precision);
return *this;
Raw = ToIntRounded();
return *this;
}
template< int Precision >
FixedInt<Precision>& FixedInt<Precision>::SetFraction( u32 fracpart )
template <int Precision>
FixedInt<Precision> &FixedInt<Precision>::SetWhole(s32 wholepart)
{
Raw = (GetWhole() * Precision) + fracpart;
return *this;
pxAssert(wholepart < (INT_MAX / Precision));
Raw = GetFraction() + (wholepart * Precision);
return *this;
}
template< int Precision >
template <int Precision>
FixedInt<Precision> &FixedInt<Precision>::SetFraction(u32 fracpart)
{
Raw = (GetWhole() * Precision) + fracpart;
return *this;
}
template <int Precision>
wxString FixedInt<Precision>::ToString() const
{
return wxsFormat( L"%d.%02d", GetWhole(), (GetFraction() * 100) / Precision );
return wxsFormat(L"%d.%02d", GetWhole(), (GetFraction() * 100) / Precision);
}
template< int Precision >
wxString FixedInt<Precision>::ToString( int fracDigits ) const
template <int Precision>
wxString FixedInt<Precision>::ToString(int fracDigits) const
{
if( fracDigits == 0 ) return wxsFormat( L"%d", GetWhole() );
if (fracDigits == 0)
return wxsFormat(L"%d", GetWhole());
pxAssert( fracDigits <= 7 ); // higher numbers would just cause overflows and bad mojo.
int mulby = (int)pow( 10.0, fracDigits );
wxString fmt=wxsFormat(L"%%d.%%0%dd", fracDigits);
return wxsFormat( fmt, GetWhole(), (GetFraction() * mulby) / Precision );
pxAssert(fracDigits <= 7); // higher numbers would just cause overflows and bad mojo.
int mulby = (int)pow(10.0, fracDigits);
wxString fmt = wxsFormat(L"%%d.%%0%dd", fracDigits);
return wxsFormat(fmt, GetWhole(), (GetFraction() * mulby) / Precision);
}
template< int Precision >
template <int Precision>
double FixedInt<Precision>::ToDouble() const
{
return ((double)Raw / (double)Precision);
return ((double)Raw / (double)Precision);
}
template< int Precision >
template <int Precision>
float FixedInt<Precision>::ToFloat() const
{
return ((float)Raw / (float)Precision);
return ((float)Raw / (float)Precision);
}
template< int Precision >
template <int Precision>
int FixedInt<Precision>::ToIntTruncated() const
{
return Raw / Precision;
return Raw / Precision;
}
template< int Precision >
template <int Precision>
int FixedInt<Precision>::ToIntRounded() const
{
return (Raw + (Precision/2)) / Precision;
return (Raw + (Precision / 2)) / Precision;
}
template< int Precision >
bool FixedInt<Precision>::TryFromString( FixedInt<Precision>& dest, const wxString& parseFrom )
template <int Precision>
bool FixedInt<Precision>::TryFromString(FixedInt<Precision> &dest, const wxString &parseFrom)
{
long whole=0, frac=0;
const wxString beforeFirst( parseFrom.BeforeFirst( L'.' ) );
const wxString afterFirst( parseFrom.AfterFirst( L'.' ).Mid(0, 5) );
bool success = true;
long whole = 0, frac = 0;
const wxString beforeFirst(parseFrom.BeforeFirst(L'.'));
const wxString afterFirst(parseFrom.AfterFirst(L'.').Mid(0, 5));
bool success = true;
if( !beforeFirst.IsEmpty() )
success = success && beforeFirst.ToLong( &whole );
if (!beforeFirst.IsEmpty())
success = success && beforeFirst.ToLong(&whole);
if( !afterFirst.IsEmpty() )
success = success && afterFirst.ToLong( &frac );
if (!afterFirst.IsEmpty())
success = success && afterFirst.ToLong(&frac);
if( !success ) return false;
if (!success)
return false;
dest.SetWhole( whole );
dest.SetWhole(whole);
if( afterFirst.Length() != 0 && frac != 0 )
{
int fracPower = (int)pow( 10.0, (int)afterFirst.Length() );
dest.SetFraction( (frac * Precision) / fracPower );
}
return true;
if (afterFirst.Length() != 0 && frac != 0) {
int fracPower = (int)pow(10.0, (int)afterFirst.Length());
dest.SetFraction((frac * Precision) / fracPower);
}
return true;
}
template< int Precision >
FixedInt<Precision> FixedInt<Precision>::FromString( const wxString& parseFrom, const FixedInt<Precision>& defval )
template <int Precision>
FixedInt<Precision> FixedInt<Precision>::FromString(const wxString &parseFrom, const FixedInt<Precision> &defval)
{
FixedInt<Precision> dest;
if( !TryFromString( dest, parseFrom ) ) return defval;
return dest;
FixedInt<Precision> dest;
if (!TryFromString(dest, parseFrom))
return defval;
return dest;
}
// This version of FromString throws a ParseError exception if the conversion fails.
template< int Precision >
FixedInt<Precision> FixedInt<Precision>::FromString( const wxString parseFrom )
template <int Precision>
FixedInt<Precision> FixedInt<Precision>::FromString(const wxString parseFrom)
{
FixedInt<Precision> dest;
if( !TryFromString( dest, parseFrom ) ) throw Exception::ParseError()
.SetDiagMsg(wxsFormat(L"Parse error on FixedInt<%d>::FromString", Precision));
FixedInt<Precision> dest;
if (!TryFromString(dest, parseFrom))
throw Exception::ParseError()
.SetDiagMsg(wxsFormat(L"Parse error on FixedInt<%d>::FromString", Precision));
return dest;
return dest;
}

View File

@ -17,16 +17,22 @@
// This macro is actually useful for about any and every possible application of C++
// equality operators.
#define OpEqu( field ) (field == right.field)
#define OpEqu(field) (field == right.field)
// Macro used for removing some of the redtape involved in defining bitfield/union helpers.
//
#define BITFIELD32() \
union { \
u32 bitset; \
struct {
#define BITFIELD32() \
union \
{ \
u32 bitset; \
struct \
{
#define BITFIELD_END }; };
#define BITFIELD_END \
} \
; \
} \
;
// ----------------------------------------------------------------------------------------
@ -42,15 +48,20 @@
class RecursionGuard
{
public:
int& Counter;
int &Counter;
RecursionGuard( int& counter ) : Counter( counter )
{ ++Counter; }
RecursionGuard(int &counter)
: Counter(counter)
{
++Counter;
}
virtual ~RecursionGuard() throw()
{ --Counter; }
virtual ~RecursionGuard() throw()
{
--Counter;
}
bool IsReentrant() const { return Counter > 1; }
bool IsReentrant() const { return Counter > 1; }
};
// --------------------------------------------------------------------------------------
@ -59,30 +70,30 @@ public:
class IActionInvocation
{
public:
virtual ~IActionInvocation() throw() {}
virtual void InvokeAction()=0;
virtual ~IActionInvocation() throw() {}
virtual void InvokeAction() = 0;
};
class ICloneable
{
public:
virtual ICloneable* Clone() const=0;
virtual ICloneable *Clone() const = 0;
};
class IDeletableObject
{
public:
virtual ~IDeletableObject() throw() {}
virtual ~IDeletableObject() throw() {}
virtual void DeleteSelf()=0;
virtual bool IsBeingDeleted()=0;
virtual void DeleteSelf() = 0;
virtual bool IsBeingDeleted() = 0;
protected:
// This function is GUI implementation dependent! It's implemented by PCSX2's AppHost,
// but if the SysCore is being linked to another front end, you'll need to implement this
// yourself. Most GUIs have built in message pumps. If a platform lacks one then you'll
// need to implement one yourself (yay?).
virtual void DoDeletion()=0;
// This function is GUI implementation dependent! It's implemented by PCSX2's AppHost,
// but if the SysCore is being linked to another front end, you'll need to implement this
// yourself. Most GUIs have built in message pumps. If a platform lacks one then you'll
// need to implement one yourself (yay?).
virtual void DoDeletion() = 0;
};
// --------------------------------------------------------------------------------------
@ -111,26 +122,26 @@ protected:
class BaseDeletableObject : public virtual IDeletableObject
{
protected:
std::atomic<bool> m_IsBeingDeleted;
std::atomic<bool> m_IsBeingDeleted;
public:
BaseDeletableObject();
virtual ~BaseDeletableObject() throw();
BaseDeletableObject();
virtual ~BaseDeletableObject() throw();
void DeleteSelf();
bool IsBeingDeleted() { return !!m_IsBeingDeleted; }
void DeleteSelf();
bool IsBeingDeleted() { return !!m_IsBeingDeleted; }
// Returns FALSE if the object is already marked for deletion, or TRUE if the app
// should schedule the object for deletion. Only schedule if TRUE is returned, otherwise
// the object could get deleted twice if two threads try to schedule it at the same time.
bool MarkForDeletion();
// Returns FALSE if the object is already marked for deletion, or TRUE if the app
// should schedule the object for deletion. Only schedule if TRUE is returned, otherwise
// the object could get deleted twice if two threads try to schedule it at the same time.
bool MarkForDeletion();
protected:
// This function is GUI implementation dependent! It's implemented by PCSX2's AppHost,
// but if the SysCore is being linked to another front end, you'll need to implement this
// yourself. Most GUIs have built in message pumps. If a platform lacks one then you'll
// need to implement one yourself (yay?).
virtual void DoDeletion();
// This function is GUI implementation dependent! It's implemented by PCSX2's AppHost,
// but if the SysCore is being linked to another front end, you'll need to implement this
// yourself. Most GUIs have built in message pumps. If a platform lacks one then you'll
// need to implement one yourself (yay?).
virtual void DoDeletion();
};
// --------------------------------------------------------------------------------------
@ -139,76 +150,76 @@ protected:
class PageProtectionMode
{
protected:
bool m_read;
bool m_write;
bool m_exec;
bool m_read;
bool m_write;
bool m_exec;
public:
PageProtectionMode()
{
All( false );
}
PageProtectionMode()
{
All(false);
}
PageProtectionMode& Read( bool allow=true )
{
m_read = allow;
return *this;
}
PageProtectionMode &Read(bool allow = true)
{
m_read = allow;
return *this;
}
PageProtectionMode& Write( bool allow=true )
{
m_write = allow;
return *this;
}
PageProtectionMode &Write(bool allow = true)
{
m_write = allow;
return *this;
}
PageProtectionMode& Execute( bool allow=true )
{
m_exec = allow;
return *this;
}
PageProtectionMode& All( bool allow=true )
{
m_read = m_write = m_exec = allow;
return *this;
}
PageProtectionMode &Execute(bool allow = true)
{
m_exec = allow;
return *this;
}
bool CanRead() const { return m_read; }
bool CanWrite() const { return m_write; }
bool CanExecute() const { return m_exec && m_read; }
bool IsNone() const { return !m_read && !m_write; }
wxString ToString() const;
PageProtectionMode &All(bool allow = true)
{
m_read = m_write = m_exec = allow;
return *this;
}
bool CanRead() const { return m_read; }
bool CanWrite() const { return m_write; }
bool CanExecute() const { return m_exec && m_read; }
bool IsNone() const { return !m_read && !m_write; }
wxString ToString() const;
};
static __fi PageProtectionMode PageAccess_None()
{
return PageProtectionMode();
return PageProtectionMode();
}
static __fi PageProtectionMode PageAccess_ReadOnly()
{
return PageProtectionMode().Read();
return PageProtectionMode().Read();
}
static __fi PageProtectionMode PageAccess_WriteOnly()
{
return PageProtectionMode().Write();
return PageProtectionMode().Write();
}
static __fi PageProtectionMode PageAccess_ReadWrite()
{
return PageAccess_ReadOnly().Write();
return PageAccess_ReadOnly().Write();
}
static __fi PageProtectionMode PageAccess_ExecOnly()
{
return PageAccess_ReadOnly().Execute();
return PageAccess_ReadOnly().Execute();
}
static __fi PageProtectionMode PageAccess_Any()
{
return PageProtectionMode().All();
return PageProtectionMode().All();
}
// --------------------------------------------------------------------------------------
@ -218,39 +229,39 @@ static __fi PageProtectionMode PageAccess_Any()
// platform prior to wxWidgets .. it should prolly be removed -- air)
namespace HostSys
{
void* MmapReserve(uptr base, size_t size);
bool MmapCommit(uptr base, size_t size, const PageProtectionMode& mode);
void MmapReset(uptr base, size_t size);
void *MmapReserve(uptr base, size_t size);
bool MmapCommit(uptr base, size_t size, const PageProtectionMode &mode);
void MmapReset(uptr base, size_t size);
void* MmapReservePtr(void* base, size_t size);
bool MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode);
void MmapResetPtr(void* base, size_t size);
void *MmapReservePtr(void *base, size_t size);
bool MmapCommitPtr(void *base, size_t size, const PageProtectionMode &mode);
void MmapResetPtr(void *base, size_t size);
// Maps a block of memory for use as a recompiled code buffer.
// Returns NULL on allocation failure.
extern void* Mmap(uptr base, size_t size);
// Maps a block of memory for use as a recompiled code buffer.
// Returns NULL on allocation failure.
extern void *Mmap(uptr base, size_t size);
// Unmaps a block allocated by SysMmap
extern void Munmap(uptr base, size_t size);
// Unmaps a block allocated by SysMmap
extern void Munmap(uptr base, size_t size);
extern void MemProtect( void* baseaddr, size_t size, const PageProtectionMode& mode );
extern void MemProtect(void *baseaddr, size_t size, const PageProtectionMode &mode);
extern void Munmap( void* base, size_t size );
extern void Munmap(void *base, size_t size);
template< uint size >
void MemProtectStatic( u8 (&arr)[size], const PageProtectionMode& mode )
{
MemProtect( arr, size, mode );
}
template <uint size>
void MemProtectStatic(u8 (&arr)[size], const PageProtectionMode &mode)
{
MemProtect(arr, size, mode);
}
}
// Safe version of Munmap -- NULLs the pointer variable immediately after free'ing it.
#define SafeSysMunmap( ptr, size ) \
((void) ( HostSys::Munmap( (uptr)(ptr), size ), (ptr) = NULL ))
#define SafeSysMunmap(ptr, size) \
((void)(HostSys::Munmap((uptr)(ptr), size), (ptr) = NULL))
extern void InitCPUTicks();
extern u64 GetTickFrequency();
extern u64 GetCPUTicks();
extern u64 GetTickFrequency();
extern u64 GetCPUTicks();
extern u64 GetPhysicalMemory();
extern wxString GetOSVersionString();

View File

@ -15,7 +15,8 @@
#pragma once
namespace HashTools {
namespace HashTools
{
/// <summary>
/// Type that represents a hashcode; returned by all hash functions.
@ -26,7 +27,5 @@ namespace HashTools {
/// </remarks>
typedef u32 hash_key_t;
hash_key_t Hash(const char* data, int len);
hash_key_t Hash(const char *data, int len);
}

View File

@ -21,7 +21,7 @@
#include <wx/gdicmn.h>
// --------------------------------------------------------------------------------------
// IniInterface (abstract base class)
// IniInterface (abstract base class)
// --------------------------------------------------------------------------------------
// This is used as an interchangable interface for both loading and saving options from an
// ini/configuration file. The LoadSave code takes an IniInterface, and the interface
@ -32,53 +32,57 @@
class IniInterface
{
protected:
wxConfigBase* m_Config;
wxConfigBase *m_Config;
public:
virtual ~IniInterface();
explicit IniInterface();
explicit IniInterface( wxConfigBase& config );
explicit IniInterface( wxConfigBase* config );
virtual ~IniInterface();
explicit IniInterface();
explicit IniInterface(wxConfigBase &config);
explicit IniInterface(wxConfigBase *config);
void SetPath( const wxString& path );
void Flush();
void SetPath(const wxString &path);
void Flush();
wxConfigBase& GetConfig() { pxAssert( m_Config ); return *m_Config; }
bool IsOk() const { return m_Config != NULL; }
wxConfigBase &GetConfig()
{
pxAssert(m_Config);
return *m_Config;
}
bool IsOk() const { return m_Config != NULL; }
virtual bool IsLoading() const=0;
bool IsSaving() const { return !IsLoading(); }
virtual bool IsLoading() const = 0;
bool IsSaving() const { return !IsLoading(); }
virtual void Entry( const wxString& var, wxString& value, const wxString defvalue=wxString() )=0;
virtual void Entry( const wxString& var, wxDirName& value, const wxDirName defvalue=wxDirName(), bool isAllowRelative=false )=0;
virtual void Entry( const wxString& var, wxFileName& value, const wxFileName defvalue=wxFileName(), bool isAllowRelative=false )=0;
virtual void Entry( const wxString& var, int& value, const int defvalue=0 )=0;
virtual void Entry( const wxString& var, uint& value, const uint defvalue=0 )=0;
virtual void Entry( const wxString& var, bool& value, const bool defvalue=false )=0;
virtual void Entry(const wxString &var, wxString &value, const wxString defvalue = wxString()) = 0;
virtual void Entry(const wxString &var, wxDirName &value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false) = 0;
virtual void Entry(const wxString &var, wxFileName &value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false) = 0;
virtual void Entry(const wxString &var, int &value, const int defvalue = 0) = 0;
virtual void Entry(const wxString &var, uint &value, const uint defvalue = 0) = 0;
virtual void Entry(const wxString &var, bool &value, const bool defvalue = false) = 0;
// This special form of Entry is provided for bitfields, which cannot be passed by reference.
virtual bool EntryBitBool( const wxString& var, bool value, const bool defvalue=false )=0;
virtual int EntryBitfield( const wxString& var, int value, const int defvalue=0 )=0;
// This special form of Entry is provided for bitfields, which cannot be passed by reference.
virtual bool EntryBitBool(const wxString &var, bool value, const bool defvalue = false) = 0;
virtual int EntryBitfield(const wxString &var, int value, const int defvalue = 0) = 0;
virtual void Entry( const wxString& var, Fixed100& value, const Fixed100 defvalue=Fixed100() )=0;
virtual void Entry(const wxString &var, Fixed100 &value, const Fixed100 defvalue = Fixed100()) = 0;
virtual void Entry( const wxString& var, wxPoint& value, const wxPoint defvalue=wxDefaultPosition )=0;
virtual void Entry( const wxString& var, wxSize& value, const wxSize defvalue=wxDefaultSize )=0;
virtual void Entry( const wxString& var, wxRect& value, const wxRect defvalue=wxDefaultRect )=0;
virtual void Entry(const wxString &var, wxPoint &value, const wxPoint defvalue = wxDefaultPosition) = 0;
virtual void Entry(const wxString &var, wxSize &value, const wxSize defvalue = wxDefaultSize) = 0;
virtual void Entry(const wxString &var, wxRect &value, const wxRect defvalue = wxDefaultRect) = 0;
template< typename T >
void EnumEntry( const wxString& var, T& value, const wxChar* const* enumArray=NULL, const T defvalue=(T)0 )
{
int tstore = (int)value;
if( enumArray == NULL )
Entry( var, tstore, defvalue );
else
_EnumEntry( var, tstore, enumArray, defvalue );
value = (T)tstore;
}
template <typename T>
void EnumEntry(const wxString &var, T &value, const wxChar *const *enumArray = NULL, const T defvalue = (T)0)
{
int tstore = (int)value;
if (enumArray == NULL)
Entry(var, tstore, defvalue);
else
_EnumEntry(var, tstore, enumArray, defvalue);
value = (T)tstore;
}
protected:
virtual void _EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, int defvalue )=0;
virtual void _EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue) = 0;
};
// --------------------------------------------------------------------------------------
@ -87,11 +91,11 @@ protected:
class ScopedIniGroup
{
protected:
IniInterface& m_mom;
IniInterface &m_mom;
public:
ScopedIniGroup( IniInterface& mommy, const wxString& group );
virtual ~ScopedIniGroup();
ScopedIniGroup(IniInterface &mommy, const wxString &group);
virtual ~ScopedIniGroup();
};
// --------------------------------------------------------------------------------------
@ -105,31 +109,31 @@ public:
class IniLoader : public IniInterface
{
public:
virtual ~IniLoader() throw();
explicit IniLoader();
explicit IniLoader( wxConfigBase& config );
explicit IniLoader( wxConfigBase* config );
virtual ~IniLoader() throw();
explicit IniLoader();
explicit IniLoader(wxConfigBase &config);
explicit IniLoader(wxConfigBase *config);
bool IsLoading() const { return true; }
bool IsLoading() const { return true; }
void Entry( const wxString& var, wxString& value, const wxString defvalue=wxEmptyString );
void Entry( const wxString& var, wxDirName& value, const wxDirName defvalue=wxDirName(), bool isAllowRelative=false );
void Entry( const wxString& var, wxFileName& value, const wxFileName defvalue=wxFileName(), bool isAllowRelative=false );
void Entry( const wxString& var, int& value, const int defvalue=0 );
void Entry( const wxString& var, uint& value, const uint defvalue=0 );
void Entry( const wxString& var, bool& value, const bool defvalue=false );
void Entry(const wxString &var, wxString &value, const wxString defvalue = wxEmptyString);
void Entry(const wxString &var, wxDirName &value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false);
void Entry(const wxString &var, wxFileName &value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false);
void Entry(const wxString &var, int &value, const int defvalue = 0);
void Entry(const wxString &var, uint &value, const uint defvalue = 0);
void Entry(const wxString &var, bool &value, const bool defvalue = false);
bool EntryBitBool( const wxString& var, bool value, const bool defvalue=false );
int EntryBitfield( const wxString& var, int value, const int defvalue=0 );
bool EntryBitBool(const wxString &var, bool value, const bool defvalue = false);
int EntryBitfield(const wxString &var, int value, const int defvalue = 0);
void Entry( const wxString& var, Fixed100& value, const Fixed100 defvalue=Fixed100() );
void Entry(const wxString &var, Fixed100 &value, const Fixed100 defvalue = Fixed100());
void Entry( const wxString& var, wxPoint& value, const wxPoint defvalue=wxDefaultPosition );
void Entry( const wxString& var, wxSize& value, const wxSize defvalue=wxDefaultSize );
void Entry( const wxString& var, wxRect& value, const wxRect defvalue=wxDefaultRect );
void Entry(const wxString &var, wxPoint &value, const wxPoint defvalue = wxDefaultPosition);
void Entry(const wxString &var, wxSize &value, const wxSize defvalue = wxDefaultSize);
void Entry(const wxString &var, wxRect &value, const wxRect defvalue = wxDefaultRect);
protected:
void _EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, int defvalue );
void _EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue);
};
// --------------------------------------------------------------------------------------
@ -143,45 +147,45 @@ protected:
class IniSaver : public IniInterface
{
public:
virtual ~IniSaver();
explicit IniSaver();
explicit IniSaver( wxConfigBase& config );
explicit IniSaver( wxConfigBase* config );
virtual ~IniSaver();
explicit IniSaver();
explicit IniSaver(wxConfigBase &config);
explicit IniSaver(wxConfigBase *config);
bool IsLoading() const { return false; }
bool IsLoading() const { return false; }
void Entry( const wxString& var, wxString& value, const wxString defvalue=wxString() );
void Entry( const wxString& var, wxDirName& value, const wxDirName defvalue=wxDirName(), bool isAllowRelative=false );
void Entry( const wxString& var, wxFileName& value, const wxFileName defvalue=wxFileName(), bool isAllowRelative=false );
void Entry( const wxString& var, int& value, const int defvalue=0 );
void Entry( const wxString& var, uint& value, const uint defvalue=0 );
void Entry( const wxString& var, bool& value, const bool defvalue=false );
void Entry(const wxString &var, wxString &value, const wxString defvalue = wxString());
void Entry(const wxString &var, wxDirName &value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false);
void Entry(const wxString &var, wxFileName &value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false);
void Entry(const wxString &var, int &value, const int defvalue = 0);
void Entry(const wxString &var, uint &value, const uint defvalue = 0);
void Entry(const wxString &var, bool &value, const bool defvalue = false);
bool EntryBitBool( const wxString& var, bool value, const bool defvalue=false );
int EntryBitfield( const wxString& var, int value, const int defvalue=0 );
bool EntryBitBool(const wxString &var, bool value, const bool defvalue = false);
int EntryBitfield(const wxString &var, int value, const int defvalue = 0);
void Entry( const wxString& var, Fixed100& value, const Fixed100 defvalue=Fixed100() );
void Entry(const wxString &var, Fixed100 &value, const Fixed100 defvalue = Fixed100());
void Entry( const wxString& var, wxPoint& value, const wxPoint defvalue=wxDefaultPosition );
void Entry( const wxString& var, wxSize& value, const wxSize defvalue=wxDefaultSize );
void Entry( const wxString& var, wxRect& value, const wxRect defvalue=wxDefaultRect );
void Entry(const wxString &var, wxPoint &value, const wxPoint defvalue = wxDefaultPosition);
void Entry(const wxString &var, wxSize &value, const wxSize defvalue = wxDefaultSize);
void Entry(const wxString &var, wxRect &value, const wxRect defvalue = wxDefaultRect);
protected:
void _EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, int defvalue );
void _EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue);
};
// ------------------------------------------------------------------------
// GCC Note: wxT() macro is required when using string token pasting. For some reason L generates
// syntax errors. >_<
//
#define IniEntry( varname ) ini.Entry( wxT(#varname), varname, varname )
#define IniEntryDirFile( varname, isAllowRelative ) ini.Entry( wxT(#varname), varname, varname, isAllowRelative )
#define IniBitfield( varname ) varname = ini.EntryBitfield( wxT(#varname), varname, varname )
#define IniBitBool( varname ) varname = ini.EntryBitBool( wxT(#varname), !!varname, varname )
#define IniEntry(varname) ini.Entry(wxT(#varname), varname, varname)
#define IniEntryDirFile(varname, isAllowRelative) ini.Entry(wxT(#varname), varname, varname, isAllowRelative)
#define IniBitfield(varname) varname = ini.EntryBitfield(wxT(#varname), varname, varname)
#define IniBitBool(varname) varname = ini.EntryBitBool(wxT(#varname), !!varname, varname)
#define IniBitfieldEx( varname, textname ) varname = ini.EntryBitfield( wxT(textname), varname, varname )
#define IniBitBoolEx( varname, textname ) varname = ini.EntryBitBool( wxT(textname), !!varname, varname )
#define IniBitfieldEx(varname, textname) varname = ini.EntryBitfield(wxT(textname), varname, varname)
#define IniBitBoolEx(varname, textname) varname = ini.EntryBitBool(wxT(textname), !!varname, varname)
//used for filenames and folder names as ini values.
//Set to app root folder, so all files and folders which are inside appRoot will be written as relative.
void SetFullBaseDir( wxDirName appRoot );
void SetFullBaseDir(wxDirName appRoot);

View File

@ -20,22 +20,22 @@
#include "Pcsx2Defs.h"
// On GCC >= 4.7, this is equivalent to __builtin_clrsb(n);
inline u32 count_leading_sign_bits(s32 n) {
// If the sign bit is 1, we invert the bits to 0 for count-leading-zero.
if (n < 0)
n = ~n;
inline u32 count_leading_sign_bits(s32 n)
{
// If the sign bit is 1, we invert the bits to 0 for count-leading-zero.
if (n < 0)
n = ~n;
// If BSR is used directly, it would have an undefined value for 0.
if (n == 0)
return 32;
// If BSR is used directly, it would have an undefined value for 0.
if (n == 0)
return 32;
// Perform our count leading zero.
// Perform our count leading zero.
#ifdef _MSC_VER
unsigned long ret;
_BitScanReverse(&ret, n);
return 31 - (u32)ret;
unsigned long ret;
_BitScanReverse(&ret, n);
return 31 - (u32)ret;
#else
return __builtin_clz(n);
return __builtin_clz(n);
#endif
}

View File

@ -16,15 +16,15 @@
#pragma once
#if defined(__POSIX__)
# include "lnx_memzero.h"
#include "lnx_memzero.h"
#else
# include "win_memzero.h"
#include "win_memzero.h"
#endif
// For 32-bit MSVC compiles, memcmp performs much worse than memcmp_mmx and
// other implementations. So for this combination only, prefer memcmp_mmx
#if defined(_MSC_VER) && !defined(_M_X86_64)
extern u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize);
extern u8 memcmp_mmx(const void *src1, const void *src2, int cmpsize);
#else
#define memcmp_mmx memcmp
#endif

View File

@ -17,69 +17,67 @@
#include <xmmintrin.h>
#define StoreDestIdx(idx) case idx: _mm_store_ps(&destxmm[idx-1][0], srcreg)
template< u8 data >
__noinline void memset_sse_a( void* dest, const size_t size )
#define StoreDestIdx(idx) \
case idx: \
_mm_store_ps(&destxmm[idx - 1][0], srcreg)
template <u8 data>
__noinline void memset_sse_a(void *dest, const size_t size)
{
const uint MZFqwc = size / 16;
const uint MZFqwc = size / 16;
pxAssert( (size & 0xf) == 0 );
pxAssert((size & 0xf) == 0);
__m128 srcreg;
__m128 srcreg;
if (data != 0)
{
static __aligned16 const u8 loadval[8] = { data,data,data,data,data,data,data,data };
srcreg = _mm_loadh_pi( _mm_load_ps( (float*)loadval ), (__m64*)loadval );
}
else
srcreg = _mm_setzero_ps();
if (data != 0) {
static __aligned16 const u8 loadval[8] = {data, data, data, data, data, data, data, data};
srcreg = _mm_loadh_pi(_mm_load_ps((float *)loadval), (__m64 *)loadval);
} else
srcreg = _mm_setzero_ps();
float (*destxmm)[4] = (float(*)[4])dest;
float(*destxmm)[4] = (float(*)[4])dest;
switch( MZFqwc & 0x07 )
{
StoreDestIdx(0x07);
StoreDestIdx(0x06);
StoreDestIdx(0x05);
StoreDestIdx(0x04);
StoreDestIdx(0x03);
StoreDestIdx(0x02);
StoreDestIdx(0x01);
}
switch (MZFqwc & 0x07) {
StoreDestIdx(0x07);
StoreDestIdx(0x06);
StoreDestIdx(0x05);
StoreDestIdx(0x04);
StoreDestIdx(0x03);
StoreDestIdx(0x02);
StoreDestIdx(0x01);
}
destxmm += (MZFqwc & 0x07);
for( uint i=0; i<MZFqwc / 8; ++i, destxmm+=8 )
{
_mm_store_ps(&destxmm[0][0], srcreg);
_mm_store_ps(&destxmm[1][0], srcreg);
_mm_store_ps(&destxmm[2][0], srcreg);
_mm_store_ps(&destxmm[3][0], srcreg);
_mm_store_ps(&destxmm[4][0], srcreg);
_mm_store_ps(&destxmm[5][0], srcreg);
_mm_store_ps(&destxmm[6][0], srcreg);
_mm_store_ps(&destxmm[7][0], srcreg);
}
destxmm += (MZFqwc & 0x07);
for (uint i = 0; i < MZFqwc / 8; ++i, destxmm += 8) {
_mm_store_ps(&destxmm[0][0], srcreg);
_mm_store_ps(&destxmm[1][0], srcreg);
_mm_store_ps(&destxmm[2][0], srcreg);
_mm_store_ps(&destxmm[3][0], srcreg);
_mm_store_ps(&destxmm[4][0], srcreg);
_mm_store_ps(&destxmm[5][0], srcreg);
_mm_store_ps(&destxmm[6][0], srcreg);
_mm_store_ps(&destxmm[7][0], srcreg);
}
};
static __fi void memzero_sse_a( void* dest, const size_t size )
static __fi void memzero_sse_a(void *dest, const size_t size)
{
memset_sse_a<0>( dest, size );
memset_sse_a<0>(dest, size);
}
#undef StoreDestIdx
template< u8 data, typename T >
__noinline void memset_sse_a( T& dest )
template <u8 data, typename T>
__noinline void memset_sse_a(T &dest)
{
static_assert( (sizeof(dest) & 0xf) == 0, "Bad size for SSE memset" );
memset_sse_a<data>( &dest, sizeof(dest) );
static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset");
memset_sse_a<data>(&dest, sizeof(dest));
}
template< typename T >
void memzero_sse_a( T& dest )
template <typename T>
void memzero_sse_a(T &dest)
{
static_assert( (sizeof(dest) & 0xf) == 0, "Bad size for SSE memset" );
memset_sse_a<0>( &dest, sizeof(dest) );
static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset");
memset_sse_a<0>(&dest, sizeof(dest));
}

View File

@ -28,12 +28,12 @@
struct PageFaultInfo
{
uptr addr;
uptr addr;
PageFaultInfo( uptr address )
{
addr = address;
}
PageFaultInfo(uptr address)
{
addr = address;
}
};
// --------------------------------------------------------------------------------------
@ -42,22 +42,22 @@ struct PageFaultInfo
class IEventListener_PageFault : public IEventDispatcher<PageFaultInfo>
{
public:
typedef PageFaultInfo EvtParams;
typedef PageFaultInfo EvtParams;
public:
virtual ~IEventListener_PageFault() throw() {}
virtual ~IEventListener_PageFault() throw() {}
virtual void DispatchEvent( const PageFaultInfo& evtinfo, bool& handled )
{
OnPageFaultEvent( evtinfo, handled );
}
virtual void DispatchEvent(const PageFaultInfo &evtinfo, bool &handled)
{
OnPageFaultEvent(evtinfo, handled);
}
virtual void DispatchEvent( const PageFaultInfo& evtinfo )
{
pxFailRel( "Don't call me, damnit. Use DispatchException instead." );
}
virtual void DispatchEvent(const PageFaultInfo &evtinfo)
{
pxFailRel("Don't call me, damnit. Use DispatchException instead.");
}
virtual void OnPageFaultEvent( const PageFaultInfo& evtinfo, bool& handled ) {}
virtual void OnPageFaultEvent(const PageFaultInfo &evtinfo, bool &handled) {}
};
// --------------------------------------------------------------------------------------
@ -66,35 +66,34 @@ public:
class EventListener_PageFault : public IEventListener_PageFault
{
public:
EventListener_PageFault();
virtual ~EventListener_PageFault() throw();
EventListener_PageFault();
virtual ~EventListener_PageFault() throw();
};
template< typename TypeToDispatchTo >
template <typename TypeToDispatchTo>
class EventListenerHelper_PageFault : public EventListener_PageFault
{
public:
TypeToDispatchTo* Owner;
TypeToDispatchTo *Owner;
public:
EventListenerHelper_PageFault( TypeToDispatchTo& dispatchTo )
{
Owner = &dispatchTo;
}
EventListenerHelper_PageFault(TypeToDispatchTo &dispatchTo)
{
Owner = &dispatchTo;
}
EventListenerHelper_PageFault( TypeToDispatchTo* dispatchTo )
{
Owner = dispatchTo;
}
EventListenerHelper_PageFault(TypeToDispatchTo *dispatchTo)
{
Owner = dispatchTo;
}
virtual ~EventListenerHelper_PageFault() throw() {}
virtual ~EventListenerHelper_PageFault() throw() {}
protected:
virtual void OnPageFaultEvent( const PageFaultInfo& info, bool& handled )
{
Owner->OnPageFaultEvent( info, handled );
}
virtual void OnPageFaultEvent(const PageFaultInfo &info, bool &handled)
{
Owner->OnPageFaultEvent(info, handled);
}
};
// --------------------------------------------------------------------------------------
@ -103,20 +102,23 @@ protected:
class SrcType_PageFault : public EventSource<IEventListener_PageFault>
{
protected:
typedef EventSource<IEventListener_PageFault> _parent;
typedef EventSource<IEventListener_PageFault> _parent;
protected:
bool m_handled;
bool m_handled;
public:
SrcType_PageFault() : m_handled(false) {}
virtual ~SrcType_PageFault() throw() { }
SrcType_PageFault()
: m_handled(false)
{
}
virtual ~SrcType_PageFault() throw() {}
bool WasHandled() const { return m_handled; }
virtual void Dispatch( const PageFaultInfo& params );
bool WasHandled() const { return m_handled; }
virtual void Dispatch(const PageFaultInfo &params);
protected:
virtual void _DispatchRaw( ListenerIterator iter, const ListenerIterator& iend, const PageFaultInfo& evt );
virtual void _DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const PageFaultInfo &evt);
};
@ -125,92 +127,92 @@ protected:
// --------------------------------------------------------------------------------------
class VirtualMemoryReserve
{
DeclareNoncopyableObject( VirtualMemoryReserve );
DeclareNoncopyableObject(VirtualMemoryReserve);
protected:
wxString m_name;
wxString m_name;
// Default size of the reserve, in bytes. Can be specified when the object is constructed.
// Is used as the reserve size when Reserve() is called, unless an override is specified
// in the Reserve parameters.
size_t m_defsize;
// Default size of the reserve, in bytes. Can be specified when the object is constructed.
// Is used as the reserve size when Reserve() is called, unless an override is specified
// in the Reserve parameters.
size_t m_defsize;
void* m_baseptr;
void *m_baseptr;
// reserved memory (in pages).
uptr m_pages_reserved;
// reserved memory (in pages).
uptr m_pages_reserved;
// Records the number of pages committed to memory.
// (metric for analysis of buffer usage)
uptr m_pages_commited;
// Records the number of pages committed to memory.
// (metric for analysis of buffer usage)
uptr m_pages_commited;
// Protection mode to be applied to committed blocks.
PageProtectionMode m_prot_mode;
// Controls write access to the entire reserve. When true (the default), the reserve
// operates normally. When set to false, all committed blocks are re-protected with
// write disabled, and accesses to uncommitted blocks (read or write) will cause a GPF
// as well.
bool m_allow_writes;
// Protection mode to be applied to committed blocks.
PageProtectionMode m_prot_mode;
// Controls write access to the entire reserve. When true (the default), the reserve
// operates normally. When set to false, all committed blocks are re-protected with
// write disabled, and accesses to uncommitted blocks (read or write) will cause a GPF
// as well.
bool m_allow_writes;
public:
VirtualMemoryReserve( const wxString& name=wxEmptyString, size_t size = 0 );
virtual ~VirtualMemoryReserve() throw()
{
Release();
}
VirtualMemoryReserve(const wxString &name = wxEmptyString, size_t size = 0);
virtual ~VirtualMemoryReserve() throw()
{
Release();
}
virtual void* Reserve( size_t size = 0, uptr base = 0, uptr upper_bounds = 0 );
virtual void* ReserveAt( uptr base = 0, uptr upper_bounds = 0 )
{
return Reserve(m_defsize, base, upper_bounds);
}
virtual void *Reserve(size_t size = 0, uptr base = 0, uptr upper_bounds = 0);
virtual void *ReserveAt(uptr base = 0, uptr upper_bounds = 0)
{
return Reserve(m_defsize, base, upper_bounds);
}
virtual void Reset();
virtual void Release();
virtual bool TryResize( uint newsize );
virtual bool Commit();
virtual void ForbidModification();
virtual void AllowModification();
virtual void Reset();
virtual void Release();
virtual bool TryResize(uint newsize);
virtual bool Commit();
bool IsOk() const { return m_baseptr != NULL; }
wxString GetName() const { return m_name; }
virtual void ForbidModification();
virtual void AllowModification();
uptr GetReserveSizeInBytes() const { return m_pages_reserved * __pagesize; }
uptr GetReserveSizeInPages() const { return m_pages_reserved; }
uint GetCommittedPageCount() const { return m_pages_commited; }
uint GetCommittedBytes() const { return m_pages_commited * __pagesize; }
bool IsOk() const { return m_baseptr != NULL; }
wxString GetName() const { return m_name; }
u8* GetPtr() { return (u8*)m_baseptr; }
const u8* GetPtr() const { return (u8*)m_baseptr; }
u8* GetPtrEnd() { return (u8*)m_baseptr + (m_pages_reserved * __pagesize); }
const u8* GetPtrEnd() const { return (u8*)m_baseptr + (m_pages_reserved * __pagesize); }
uptr GetReserveSizeInBytes() const { return m_pages_reserved * __pagesize; }
uptr GetReserveSizeInPages() const { return m_pages_reserved; }
uint GetCommittedPageCount() const { return m_pages_commited; }
uint GetCommittedBytes() const { return m_pages_commited * __pagesize; }
VirtualMemoryReserve& SetName( const wxString& newname );
VirtualMemoryReserve& SetBaseAddr( uptr newaddr );
VirtualMemoryReserve& SetPageAccessOnCommit( const PageProtectionMode& mode );
u8 *GetPtr() { return (u8 *)m_baseptr; }
const u8 *GetPtr() const { return (u8 *)m_baseptr; }
u8 *GetPtrEnd() { return (u8 *)m_baseptr + (m_pages_reserved * __pagesize); }
const u8 *GetPtrEnd() const { return (u8 *)m_baseptr + (m_pages_reserved * __pagesize); }
operator void*() { return m_baseptr; }
operator const void*() const { return m_baseptr; }
VirtualMemoryReserve &SetName(const wxString &newname);
VirtualMemoryReserve &SetBaseAddr(uptr newaddr);
VirtualMemoryReserve &SetPageAccessOnCommit(const PageProtectionMode &mode);
operator u8*() { return (u8*)m_baseptr; }
operator const u8*() const { return (u8*)m_baseptr; }
operator void *() { return m_baseptr; }
operator const void *() const { return m_baseptr; }
u8& operator[](uint idx)
{
pxAssert(idx < (m_pages_reserved * __pagesize));
return *((u8*)m_baseptr + idx);
}
operator u8 *() { return (u8 *)m_baseptr; }
operator const u8 *() const { return (u8 *)m_baseptr; }
const u8& operator[](uint idx) const
{
pxAssert(idx < (m_pages_reserved * __pagesize));
return *((u8*)m_baseptr + idx);
}
u8 &operator[](uint idx)
{
pxAssert(idx < (m_pages_reserved * __pagesize));
return *((u8 *)m_baseptr + idx);
}
const u8 &operator[](uint idx) const
{
pxAssert(idx < (m_pages_reserved * __pagesize));
return *((u8 *)m_baseptr + idx);
}
protected:
virtual void ReprotectCommittedBlocks( const PageProtectionMode& newmode );
virtual void ReprotectCommittedBlocks(const PageProtectionMode &newmode);
};
// --------------------------------------------------------------------------------------
@ -218,80 +220,79 @@ protected:
// --------------------------------------------------------------------------------------
class BaseVmReserveListener : public VirtualMemoryReserve
{
DeclareNoncopyableObject( BaseVmReserveListener );
DeclareNoncopyableObject(BaseVmReserveListener);
typedef VirtualMemoryReserve _parent;
typedef VirtualMemoryReserve _parent;
protected:
EventListenerHelper_PageFault<BaseVmReserveListener> m_pagefault_listener;
EventListenerHelper_PageFault<BaseVmReserveListener> m_pagefault_listener;
// Incremental size by which the buffer grows (in pages)
uptr m_blocksize;
// Incremental size by which the buffer grows (in pages)
uptr m_blocksize;
public:
BaseVmReserveListener( const wxString& name, size_t size = 0 );
virtual ~BaseVmReserveListener() throw() { }
BaseVmReserveListener(const wxString &name, size_t size = 0);
virtual ~BaseVmReserveListener() throw() {}
operator void*() { return m_baseptr; }
operator const void*() const { return m_baseptr; }
operator void *() { return m_baseptr; }
operator const void *() const { return m_baseptr; }
operator u8*() { return (u8*)m_baseptr; }
operator const u8*() const { return (u8*)m_baseptr; }
operator u8 *() { return (u8 *)m_baseptr; }
operator const u8 *() const { return (u8 *)m_baseptr; }
using _parent::operator[];
using _parent::operator[];
void OnPageFaultEvent( const PageFaultInfo& info, bool& handled );
void OnPageFaultEvent(const PageFaultInfo &info, bool &handled);
virtual uptr SetBlockSize( uptr bytes )
{
m_blocksize = (bytes + __pagesize - 1) / __pagesize;
return m_blocksize * __pagesize;
}
virtual uptr SetBlockSize(uptr bytes)
{
m_blocksize = (bytes + __pagesize - 1) / __pagesize;
return m_blocksize * __pagesize;
}
virtual void Reset()
{
_parent::Reset();
}
virtual void Reset()
{
_parent::Reset();
}
protected:
// This function is called from OnPageFaultEvent after the address has been translated
// and confirmed to apply to this reserved area in question. OnPageFaultEvent contains
// a try/catch exception handler, which ensures "reasonable" error response behavior if
// this function throws exceptions.
//
// Important: This method is called from the context of an exception/signal handler. On
// Windows this isn't a big deal (most operations are ok). On Linux, however, logging
// and other facilities are probably not a good idea.
virtual void DoCommitAndProtect(uptr offset) = 0;
// This function is called from OnPageFaultEvent after the address has been translated
// and confirmed to apply to this reserved area in question. OnPageFaultEvent contains
// a try/catch exception handler, which ensures "reasonable" error response behavior if
// this function throws exceptions.
//
// Important: This method is called from the context of an exception/signal handler. On
// Windows this isn't a big deal (most operations are ok). On Linux, however, logging
// and other facilities are probably not a good idea.
virtual void DoCommitAndProtect( uptr offset )=0;
// This function is called for every committed block.
virtual void OnCommittedBlock(void *block) = 0;
// This function is called for every committed block.
virtual void OnCommittedBlock( void* block )=0;
virtual void CommitBlocks( uptr page, uint blocks );
virtual void CommitBlocks(uptr page, uint blocks);
};
#ifdef __POSIX__
# define PCSX2_PAGEFAULT_PROTECT
# define PCSX2_PAGEFAULT_EXCEPT
#define PCSX2_PAGEFAULT_PROTECT
#define PCSX2_PAGEFAULT_EXCEPT
#elif defined( _WIN32 )
#elif defined(_WIN32)
struct _EXCEPTION_POINTERS;
extern int SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS* eps);
extern int SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS *eps);
# define PCSX2_PAGEFAULT_PROTECT __try
# define PCSX2_PAGEFAULT_EXCEPT __except(SysPageFaultExceptionFilter(GetExceptionInformation())) {}
#define PCSX2_PAGEFAULT_PROTECT __try
#define PCSX2_PAGEFAULT_EXCEPT \
__except (SysPageFaultExceptionFilter(GetExceptionInformation())) {}
#else
# error PCSX2 - Unsupported operating system platform.
#error PCSX2 - Unsupported operating system platform.
#endif
extern void pxInstallSignalHandler();
extern void _platform_InstallSignalHandler();
#include "Threading.h"
extern SrcType_PageFault* Source_PageFault;
extern Threading::Mutex PageFault_Mutex;
extern SrcType_PageFault *Source_PageFault;
extern Threading::Mutex PageFault_Mutex;

View File

@ -18,7 +18,7 @@
#include <wx/filename.h>
#include "StringHelpers.h"
#define g_MaxPath 255 // 255 is safer with antiquated Win32 ASCII APIs.
#define g_MaxPath 255 // 255 is safer with antiquated Win32 ASCII APIs.
// --------------------------------------------------------------------------------------
// wxDirName
@ -26,164 +26,180 @@
class wxDirName : protected wxFileName
{
public:
explicit wxDirName( const wxFileName& src )
{
Assign( src.GetPath(), wxEmptyString );
}
explicit wxDirName(const wxFileName &src)
{
Assign(src.GetPath(), wxEmptyString);
}
wxDirName() : wxFileName() {}
wxDirName( const wxDirName& src ) : wxFileName( src ) { }
explicit wxDirName( const char* src ) { Assign( fromUTF8(src) ); }
explicit wxDirName( const wxString& src ) { Assign( src ); }
wxDirName()
: wxFileName()
{
}
wxDirName(const wxDirName &src)
: wxFileName(src)
{
}
explicit wxDirName(const char *src) { Assign(fromUTF8(src)); }
explicit wxDirName(const wxString &src) { Assign(src); }
// ------------------------------------------------------------------------
void Assign( const wxString& volume, const wxString& path )
{
wxFileName::Assign( volume, path, wxEmptyString );
}
// ------------------------------------------------------------------------
void Assign(const wxString &volume, const wxString &path)
{
wxFileName::Assign(volume, path, wxEmptyString);
}
void Assign( const wxString& path )
{
wxFileName::Assign( path, wxEmptyString );
}
void Assign(const wxString &path)
{
wxFileName::Assign(path, wxEmptyString);
}
void Assign( const wxDirName& path )
{
wxFileName::Assign( path );
}
void Assign(const wxDirName &path)
{
wxFileName::Assign(path);
}
void Clear() { wxFileName::Clear(); }
void Clear() { wxFileName::Clear(); }
wxCharBuffer ToUTF8() const { return GetPath().ToUTF8(); }
wxCharBuffer ToAscii() const { return GetPath().ToAscii(); }
wxString ToString() const { return GetPath(); }
wxCharBuffer ToUTF8() const { return GetPath().ToUTF8(); }
wxCharBuffer ToAscii() const { return GetPath().ToAscii(); }
wxString ToString() const { return GetPath(); }
// ------------------------------------------------------------------------
bool IsWritable() const { return IsDirWritable(); }
bool IsReadable() const { return IsDirReadable(); }
bool Exists() const { return DirExists(); }
bool FileExists() const { return wxFileName::FileExists(); }
bool IsOk() const { return wxFileName::IsOk(); }
bool IsRelative() const { return wxFileName::IsRelative(); }
bool IsAbsolute() const { return wxFileName::IsAbsolute(); }
// ------------------------------------------------------------------------
bool IsWritable() const { return IsDirWritable(); }
bool IsReadable() const { return IsDirReadable(); }
bool Exists() const { return DirExists(); }
bool FileExists() const { return wxFileName::FileExists(); }
bool IsOk() const { return wxFileName::IsOk(); }
bool IsRelative() const { return wxFileName::IsRelative(); }
bool IsAbsolute() const { return wxFileName::IsAbsolute(); }
bool SameAs( const wxDirName& filepath ) const
{
return wxFileName::SameAs( filepath );
}
bool SameAs(const wxDirName &filepath) const
{
return wxFileName::SameAs(filepath);
}
//Returns true if the file is somewhere inside this directory (and both file and directory are not relative).
bool IsContains( const wxFileName& file ) const
{
if( this->IsRelative() || file.IsRelative() )
return false;
//Returns true if the file is somewhere inside this directory (and both file and directory are not relative).
bool IsContains(const wxFileName &file) const
{
if (this->IsRelative() || file.IsRelative())
return false;
wxFileName f( file );
wxFileName f(file);
while( 1 )
{
if( this->SameAs( wxDirName(f.GetPath()) ) )
return true;
while (1) {
if (this->SameAs(wxDirName(f.GetPath())))
return true;
if( f.GetDirCount() == 0 )
return false;
if (f.GetDirCount() == 0)
return false;
f.RemoveLastDir();
}
f.RemoveLastDir();
}
return false;
}
return false;
}
bool IsContains( const wxDirName& dir ) const
{
return IsContains( (wxFileName)dir );
}
bool IsContains(const wxDirName &dir) const
{
return IsContains((wxFileName)dir);
}
//Auto relative works as follows:
// 1. if either base or subject are relative, return subject (should never be used with relative paths).
// 2. else if subject is somewhere inside base folder, then result is subject relative to base.
// 3. (windows only, implicitly) else if subject is on the same driveletter as base, result is absolute path of subject without the driveletter.
// 4. else, result is absolute path of subject.
//
// returns ok if both this and base are absolute paths.
static wxString MakeAutoRelativeTo(const wxFileName _subject, const wxString& pathbase)
{
wxFileName subject( _subject );
wxDirName base ( pathbase );
if( base.IsRelative() || subject.IsRelative() )
return subject.GetFullPath();
//Auto relative works as follows:
// 1. if either base or subject are relative, return subject (should never be used with relative paths).
// 2. else if subject is somewhere inside base folder, then result is subject relative to base.
// 3. (windows only, implicitly) else if subject is on the same driveletter as base, result is absolute path of subject without the driveletter.
// 4. else, result is absolute path of subject.
//
// returns ok if both this and base are absolute paths.
static wxString MakeAutoRelativeTo(const wxFileName _subject, const wxString &pathbase)
{
wxFileName subject(_subject);
wxDirName base(pathbase);
if (base.IsRelative() || subject.IsRelative())
return subject.GetFullPath();
wxString bv( base.GetVolume() ); bv.MakeUpper();
wxString sv( subject.GetVolume() ); sv.MakeUpper();
wxString bv(base.GetVolume());
bv.MakeUpper();
wxString sv(subject.GetVolume());
sv.MakeUpper();
if( base.IsContains( subject ) )
{
subject.MakeRelativeTo( base.GetFullPath() );
}
else if( base.HasVolume() && subject.HasVolume() && bv == sv )
{
wxString unusedVolume;
wxString pathSansVolume;
subject.SplitVolume(subject.GetFullPath(), &unusedVolume, &pathSansVolume);
subject = pathSansVolume;
}
//implicit else: this stays fully absolute
if (base.IsContains(subject)) {
subject.MakeRelativeTo(base.GetFullPath());
} else if (base.HasVolume() && subject.HasVolume() && bv == sv) {
wxString unusedVolume;
wxString pathSansVolume;
subject.SplitVolume(subject.GetFullPath(), &unusedVolume, &pathSansVolume);
subject = pathSansVolume;
}
//implicit else: this stays fully absolute
return subject.GetFullPath();
}
return subject.GetFullPath();
}
static wxString MakeAutoRelativeTo(const wxDirName subject, const wxString& pathbase)
{
return MakeAutoRelativeTo( wxFileName( subject ), pathbase );
}
static wxString MakeAutoRelativeTo(const wxDirName subject, const wxString &pathbase)
{
return MakeAutoRelativeTo(wxFileName(subject), pathbase);
}
// Returns the number of sub folders in this directory path
size_t GetCount() const { return GetDirCount(); }
// Returns the number of sub folders in this directory path
size_t GetCount() const { return GetDirCount(); }
// ------------------------------------------------------------------------
wxFileName Combine( const wxFileName& right ) const;
wxDirName Combine( const wxDirName& right ) const;
// ------------------------------------------------------------------------
wxFileName Combine(const wxFileName &right) const;
wxDirName Combine(const wxDirName &right) const;
// removes the lastmost directory from the path
void RemoveLast() { wxFileName::RemoveDir(GetCount() - 1); }
// removes the lastmost directory from the path
void RemoveLast() { wxFileName::RemoveDir(GetCount() - 1); }
wxDirName& Normalize( int flags = wxPATH_NORM_ALL, const wxString& cwd = wxEmptyString );
wxDirName& MakeRelativeTo( const wxString& pathBase = wxEmptyString );
wxDirName& MakeAbsolute( const wxString& cwd = wxEmptyString );
wxDirName &Normalize(int flags = wxPATH_NORM_ALL, const wxString &cwd = wxEmptyString);
wxDirName &MakeRelativeTo(const wxString &pathBase = wxEmptyString);
wxDirName &MakeAbsolute(const wxString &cwd = wxEmptyString);
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
void AssignCwd( const wxString& volume = wxEmptyString ) { wxFileName::AssignCwd( volume ); }
bool SetCwd() { return wxFileName::SetCwd(); }
void AssignCwd(const wxString &volume = wxEmptyString) { wxFileName::AssignCwd(volume); }
bool SetCwd() { return wxFileName::SetCwd(); }
// wxWidgets is missing the const qualifier for this one! Shame!
void Rmdir();
bool Mkdir();
// wxWidgets is missing the const qualifier for this one! Shame!
void Rmdir();
bool Mkdir();
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
wxDirName& operator=(const wxDirName& dirname) { Assign( dirname ); return *this; }
wxDirName& operator=(const wxString& dirname) { Assign( dirname ); return *this; }
wxDirName& operator=(const char* dirname) { Assign( fromUTF8(dirname) ); return *this; }
wxDirName &operator=(const wxDirName &dirname)
{
Assign(dirname);
return *this;
}
wxDirName &operator=(const wxString &dirname)
{
Assign(dirname);
return *this;
}
wxDirName &operator=(const char *dirname)
{
Assign(fromUTF8(dirname));
return *this;
}
wxFileName operator+( const wxFileName& right ) const { return Combine( right ); }
wxDirName operator+( const wxDirName& right ) const { return Combine( right ); }
wxFileName operator+( const wxString& right ) const { return Combine( wxFileName(right) ); }
wxFileName operator+( const char* right ) const { return Combine( wxFileName(fromUTF8(right)) ); }
wxFileName operator+(const wxFileName &right) const { return Combine(right); }
wxDirName operator+(const wxDirName &right) const { return Combine(right); }
wxFileName operator+(const wxString &right) const { return Combine(wxFileName(right)); }
wxFileName operator+(const char *right) const { return Combine(wxFileName(fromUTF8(right))); }
bool operator==(const wxDirName& filename) const { return SameAs(filename); }
bool operator!=(const wxDirName& filename) const { return !SameAs(filename); }
bool operator==(const wxDirName &filename) const { return SameAs(filename); }
bool operator!=(const wxDirName &filename) const { return !SameAs(filename); }
bool operator==(const wxFileName& filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxFileName& filename) const { return !SameAs(wxDirName(filename)); }
bool operator==(const wxFileName &filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxFileName &filename) const { return !SameAs(wxDirName(filename)); }
// compare with a filename string interpreted as a native file name
bool operator==(const wxString& filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxString& filename) const { return !SameAs(wxDirName(filename)); }
// compare with a filename string interpreted as a native file name
bool operator==(const wxString &filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxString &filename) const { return !SameAs(wxDirName(filename)); }
const wxFileName& GetFilename() const { return *this; }
wxFileName& GetFilename() { return *this; }
const wxFileName &GetFilename() const { return *this; }
wxFileName &GetFilename() { return *this; }
};
// --------------------------------------------------------------------------------------
@ -195,20 +211,20 @@ public:
//
namespace Path
{
extern bool IsRelative( const wxString& path );
extern s64 GetFileSize( const wxString& path );
extern bool IsRelative(const wxString &path);
extern s64 GetFileSize(const wxString &path);
extern wxString Normalize( const wxString& srcpath );
extern wxString Normalize( const wxDirName& srcpath );
extern wxString MakeAbsolute( const wxString& srcpath );
extern wxString Normalize(const wxString &srcpath);
extern wxString Normalize(const wxDirName &srcpath);
extern wxString MakeAbsolute(const wxString &srcpath);
extern wxString Combine( const wxString& srcPath, const wxString& srcFile );
extern wxString Combine( const wxDirName& srcPath, const wxFileName& srcFile );
extern wxString Combine( const wxString& srcPath, const wxDirName& srcFile );
extern wxString ReplaceExtension( const wxString& src, const wxString& ext );
extern wxString ReplaceFilename( const wxString& src, const wxString& newfilename );
extern wxString GetFilename( const wxString& src );
extern wxString GetDirectory( const wxString& src );
extern wxString GetFilenameWithoutExt( const wxString& src );
extern wxString GetRootDirectory( const wxString& src );
extern wxString Combine(const wxString &srcPath, const wxString &srcFile);
extern wxString Combine(const wxDirName &srcPath, const wxFileName &srcFile);
extern wxString Combine(const wxString &srcPath, const wxDirName &srcFile);
extern wxString ReplaceExtension(const wxString &src, const wxString &ext);
extern wxString ReplaceFilename(const wxString &src, const wxString &newfilename);
extern wxString GetFilename(const wxString &src);
extern wxString GetDirectory(const wxString &src);
extern wxString GetFilenameWithoutExt(const wxString &src);
extern wxString GetRootDirectory(const wxString &src);
}

View File

@ -15,43 +15,42 @@
#pragma once
namespace Perf {
namespace Perf
{
struct Info
{
uptr m_x86;
u32 m_size;
char m_symbol[20];
// The idea is to keep static zones that are set only
// once.
bool m_dynamic;
struct Info
{
uptr m_x86;
u32 m_size;
char m_symbol[20];
// The idea is to keep static zones that are set only
// once.
bool m_dynamic;
Info(uptr x86, u32 size, const char* symbol);
Info(uptr x86, u32 size, const char* symbol, u32 pc);
void Print(FILE* fp);
};
Info(uptr x86, u32 size, const char *symbol);
Info(uptr x86, u32 size, const char *symbol, u32 pc);
void Print(FILE *fp);
};
class InfoVector
{
std::vector<Info> m_v;
char m_prefix[20];
class InfoVector
{
std::vector<Info> m_v;
char m_prefix[20];
public:
public:
InfoVector(const char *prefix);
InfoVector(const char* prefix);
void print(FILE *fp);
void map(uptr x86, u32 size, const char *symbol);
void map(uptr x86, u32 size, u32 pc);
void reset();
};
void print(FILE* fp);
void map(uptr x86, u32 size, const char* symbol);
void map(uptr x86, u32 size, u32 pc);
void reset();
void dump();
void dump_and_reset();
};
void dump();
void dump_and_reset();
extern InfoVector any;
extern InfoVector ee;
extern InfoVector iop;
extern InfoVector vu;
extern InfoVector any;
extern InfoVector ee;
extern InfoVector iop;
extern InfoVector vu;
}

View File

@ -25,38 +25,38 @@ namespace Threading
// --------------------------------------------------------------------------------------
// ThreadDeleteEvent
// --------------------------------------------------------------------------------------
class EventListener_Thread : public IEventDispatcher<int>
{
public:
typedef int EvtParams;
class EventListener_Thread : public IEventDispatcher<int>
{
public:
typedef int EvtParams;
protected:
pxThread* m_thread;
protected:
pxThread *m_thread;
public:
EventListener_Thread()
{
m_thread = NULL;
}
public:
EventListener_Thread()
{
m_thread = NULL;
}
virtual ~EventListener_Thread() throw() {}
virtual ~EventListener_Thread() throw() {}
void SetThread( pxThread& thr ) { m_thread = &thr; }
void SetThread( pxThread* thr ) { m_thread = thr; }
void SetThread(pxThread &thr) { m_thread = &thr; }
void SetThread(pxThread *thr) { m_thread = thr; }
void DispatchEvent( const int& params )
{
OnThreadCleanup();
}
void DispatchEvent(const int &params)
{
OnThreadCleanup();
}
protected:
// Invoked by the pxThread when the thread execution is ending. This is
// typically more useful than a delete listener since the extended thread information
// provided by virtualized functions/methods will be available.
// Important! This event is executed *by the thread*, so care must be taken to ensure
// thread sync when necessary (posting messages to the main thread, etc).
virtual void OnThreadCleanup()=0;
};
protected:
// Invoked by the pxThread when the thread execution is ending. This is
// typically more useful than a delete listener since the extended thread information
// provided by virtualized functions/methods will be available.
// Important! This event is executed *by the thread*, so care must be taken to ensure
// thread sync when necessary (posting messages to the main thread, etc).
virtual void OnThreadCleanup() = 0;
};
// --------------------------------------------------------------------------------------
// pxThread - Helper class for the basics of starting/managing persistent threads.
@ -85,122 +85,123 @@ namespace Threading
// no dependency options for ensuring correct static var initializations). Use heap
// allocation to create thread objects instead.
//
class pxThread
{
DeclareNoncopyableObject(pxThread);
class pxThread
{
DeclareNoncopyableObject(pxThread);
friend void pxYield( int ms );
friend void pxYield(int ms);
protected:
wxString m_name; // diagnostic name for our thread.
pthread_t m_thread;
uptr m_native_id; // typically an id, but implementing platforms can do whatever.
uptr m_native_handle; // typically a pointer/handle, but implementing platforms can do whatever.
protected:
wxString m_name; // diagnostic name for our thread.
pthread_t m_thread;
uptr m_native_id; // typically an id, but implementing platforms can do whatever.
uptr m_native_handle; // typically a pointer/handle, but implementing platforms can do whatever.
Semaphore m_sem_event; // general wait event that's needed by most threads
Semaphore m_sem_startup; // startup sync tool
Mutex m_mtx_InThread; // used for canceling and closing threads in a deadlock-safe manner
MutexRecursive m_mtx_start; // used to lock the Start() code from starting simultaneous threads accidentally.
Mutex m_mtx_ThreadName;
Semaphore m_sem_event; // general wait event that's needed by most threads
Semaphore m_sem_startup; // startup sync tool
Mutex m_mtx_InThread; // used for canceling and closing threads in a deadlock-safe manner
MutexRecursive m_mtx_start; // used to lock the Start() code from starting simultaneous threads accidentally.
Mutex m_mtx_ThreadName;
std::atomic<bool> m_detached; // a boolean value which indicates if the m_thread handle is valid
std::atomic<bool> m_running; // set true by Start(), and set false by Cancel(), Block(), etc.
std::atomic<bool> m_detached; // a boolean value which indicates if the m_thread handle is valid
std::atomic<bool> m_running; // set true by Start(), and set false by Cancel(), Block(), etc.
// exception handle, set non-NULL if the thread terminated with an exception
// Use RethrowException() to re-throw the exception using its original exception type.
ScopedPtrMT<BaseException> m_except;
// exception handle, set non-NULL if the thread terminated with an exception
// Use RethrowException() to re-throw the exception using its original exception type.
ScopedPtrMT<BaseException> m_except;
EventSource<EventListener_Thread> m_evtsrc_OnDelete;
EventSource<EventListener_Thread> m_evtsrc_OnDelete;
public:
virtual ~pxThread() throw();
pxThread( const wxString& name=L"pxThread" );
public:
virtual ~pxThread() throw();
pxThread(const wxString &name = L"pxThread");
pthread_t GetId() const { return m_thread; }
u64 GetCpuTime() const;
pthread_t GetId() const { return m_thread; }
u64 GetCpuTime() const;
virtual void Start();
virtual void Cancel( bool isBlocking = true );
virtual bool Cancel( const wxTimeSpan& timeout );
virtual bool Detach();
virtual void Block();
virtual bool Block( const wxTimeSpan& timeout );
virtual void RethrowException() const;
virtual void Start();
virtual void Cancel(bool isBlocking = true);
virtual bool Cancel(const wxTimeSpan &timeout);
virtual bool Detach();
virtual void Block();
virtual bool Block(const wxTimeSpan &timeout);
virtual void RethrowException() const;
void AddListener( EventListener_Thread& evt );
void AddListener( EventListener_Thread* evt )
{
if( evt == NULL ) return;
AddListener( *evt );
}
void AddListener(EventListener_Thread &evt);
void AddListener(EventListener_Thread *evt)
{
if (evt == NULL)
return;
AddListener(*evt);
}
void WaitOnSelf( Semaphore& mutex ) const;
void WaitOnSelf( Mutex& mutex ) const;
bool WaitOnSelf( Semaphore& mutex, const wxTimeSpan& timeout ) const;
bool WaitOnSelf( Mutex& mutex, const wxTimeSpan& timeout ) const;
void WaitOnSelf(Semaphore &mutex) const;
void WaitOnSelf(Mutex &mutex) const;
bool WaitOnSelf(Semaphore &mutex, const wxTimeSpan &timeout) const;
bool WaitOnSelf(Mutex &mutex, const wxTimeSpan &timeout) const;
bool IsRunning() const;
bool IsSelf() const;
bool HasPendingException() const { return !!m_except; }
bool IsRunning() const;
bool IsSelf() const;
bool HasPendingException() const { return !!m_except; }
wxString GetName() const;
void SetName( const wxString& newname );
wxString GetName() const;
void SetName(const wxString &newname);
protected:
// Extending classes should always implement your own OnStart(), which is called by
// Start() once necessary locks have been obtained. Do not override Start() directly
// unless you're really sure that's what you need to do. ;)
virtual void OnStart();
protected:
// Extending classes should always implement your own OnStart(), which is called by
// Start() once necessary locks have been obtained. Do not override Start() directly
// unless you're really sure that's what you need to do. ;)
virtual void OnStart();
virtual void OnStartInThread();
virtual void OnStartInThread();
// This is called when the thread has been canceled or exits normally. The pxThread
// automatically binds it to the pthread cleanup routines as soon as the thread starts.
virtual void OnCleanupInThread();
// This is called when the thread has been canceled or exits normally. The pxThread
// automatically binds it to the pthread cleanup routines as soon as the thread starts.
virtual void OnCleanupInThread();
// Implemented by derived class to perform actual threaded task!
virtual void ExecuteTaskInThread()=0;
// Implemented by derived class to perform actual threaded task!
virtual void ExecuteTaskInThread() = 0;
void TestCancel() const;
void TestCancel() const;
// Yields this thread to other threads and checks for cancellation. A sleeping thread should
// always test for cancellation, however if you really don't want to, you can use Threading::Sleep()
// or better yet, disable cancellation of the thread completely with DisableCancellation().
//
// Parameters:
// ms - 'minimum' yield time in milliseconds (rough -- typically yields are longer by 1-5ms
// depending on operating system/platform). If ms is 0 or unspecified, then a single
// timeslice is yielded to other contending threads. If no threads are contending for
// time when ms==0, then no yield is done, but cancellation is still tested.
void Yield( int ms = 0 )
{
pxAssert( IsSelf() );
Threading::Sleep( ms );
TestCancel();
}
// Yields this thread to other threads and checks for cancellation. A sleeping thread should
// always test for cancellation, however if you really don't want to, you can use Threading::Sleep()
// or better yet, disable cancellation of the thread completely with DisableCancellation().
//
// Parameters:
// ms - 'minimum' yield time in milliseconds (rough -- typically yields are longer by 1-5ms
// depending on operating system/platform). If ms is 0 or unspecified, then a single
// timeslice is yielded to other contending threads. If no threads are contending for
// time when ms==0, then no yield is done, but cancellation is still tested.
void Yield(int ms = 0)
{
pxAssert(IsSelf());
Threading::Sleep(ms);
TestCancel();
}
void FrankenMutex( Mutex& mutex );
void FrankenMutex(Mutex &mutex);
bool AffinityAssert_AllowFromSelf( const DiagnosticOrigin& origin ) const;
bool AffinityAssert_DisallowFromSelf( const DiagnosticOrigin& origin ) const;
bool AffinityAssert_AllowFromSelf(const DiagnosticOrigin &origin) const;
bool AffinityAssert_DisallowFromSelf(const DiagnosticOrigin &origin) const;
// ----------------------------------------------------------------------------
// Section of methods for internal use only.
// ----------------------------------------------------------------------------
// Section of methods for internal use only.
void _platform_specific_OnStartInThread();
void _platform_specific_OnCleanupInThread();
bool _basecancel();
void _selfRunningTest( const wxChar* name ) const;
void _DoSetThreadName( const wxString& name );
void _DoSetThreadName( const char* name );
void _internal_execute();
void _try_virtual_invoke( void (pxThread::*method)() );
void _ThreadCleanup();
void _platform_specific_OnStartInThread();
void _platform_specific_OnCleanupInThread();
bool _basecancel();
void _selfRunningTest(const wxChar *name) const;
void _DoSetThreadName(const wxString &name);
void _DoSetThreadName(const char *name);
void _internal_execute();
void _try_virtual_invoke(void (pxThread::*method)());
void _ThreadCleanup();
static void* _internal_callback( void* func );
static void _pt_callback_cleanup( void* handle );
};
static void *_internal_callback(void *func);
static void _pt_callback_cleanup(void *handle);
};
// --------------------------------------------------------------------------------------
@ -240,32 +241,32 @@ namespace Threading
// into smaller sections. For example, if you have 20,000 items to process, the task
// can be divided into two threads of 10,000 items each.
//
class BaseTaskThread : public pxThread
{
protected:
std::atomic<bool> m_Done;
std::atomic<bool> m_TaskPending;
Semaphore m_post_TaskComplete;
Mutex m_lock_TaskComplete;
class BaseTaskThread : public pxThread
{
protected:
std::atomic<bool> m_Done;
std::atomic<bool> m_TaskPending;
Semaphore m_post_TaskComplete;
Mutex m_lock_TaskComplete;
public:
virtual ~BaseTaskThread() throw() {}
BaseTaskThread() :
m_Done( false )
, m_TaskPending( false )
, m_post_TaskComplete()
{
}
public:
virtual ~BaseTaskThread() throw() {}
BaseTaskThread()
: m_Done(false)
, m_TaskPending(false)
, m_post_TaskComplete()
{
}
void Block();
void PostTask();
void WaitForResult();
void Block();
void PostTask();
void WaitForResult();
protected:
// Abstract method run when a task has been posted. Implementing classes should do
// all your necessary processing work here.
virtual void Task()=0;
protected:
// Abstract method run when a task has been posted. Implementing classes should do
// all your necessary processing work here.
virtual void Task() = 0;
virtual void ExecuteTaskInThread();
};
virtual void ExecuteTaskInThread();
};
}

View File

@ -16,7 +16,7 @@
#pragma once
#ifdef __WXMSW__
# include <wx/msw/wrapwin.h>
#include <wx/msw/wrapwin.h>
#else
//////////////////////////////////////////////////////////////////////////////////////////
@ -27,7 +27,7 @@
// check, so that we don't have to do it explicitly in every instance where it might
// be needed from non-Win32-specific files
#define NOMINMAX // Disables other libs inclusion of their own min/max macros (we use std instead)
#define NOMINMAX // Disables other libs inclusion of their own min/max macros (we use std instead)
#ifdef _WIN32

View File

@ -22,69 +22,69 @@ namespace Threading
// --------------------------------------------------------------------------------------
// RwMutex
// --------------------------------------------------------------------------------------
class RwMutex
{
DeclareNoncopyableObject(RwMutex);
class RwMutex
{
DeclareNoncopyableObject(RwMutex);
protected:
pthread_rwlock_t m_rwlock;
protected:
pthread_rwlock_t m_rwlock;
public:
RwMutex();
virtual ~RwMutex() throw();
virtual void AcquireRead();
virtual void AcquireWrite();
virtual bool TryAcquireRead();
virtual bool TryAcquireWrite();
public:
RwMutex();
virtual ~RwMutex() throw();
virtual void Release();
};
virtual void AcquireRead();
virtual void AcquireWrite();
virtual bool TryAcquireRead();
virtual bool TryAcquireWrite();
virtual void Release();
};
// --------------------------------------------------------------------------------------
// BaseScopedReadWriteLock
// --------------------------------------------------------------------------------------
class BaseScopedReadWriteLock
{
DeclareNoncopyableObject(BaseScopedReadWriteLock);
class BaseScopedReadWriteLock
{
DeclareNoncopyableObject(BaseScopedReadWriteLock);
protected:
RwMutex& m_lock;
bool m_IsLocked;
protected:
RwMutex &m_lock;
bool m_IsLocked;
public:
BaseScopedReadWriteLock( RwMutex& locker )
: m_lock( locker )
{
}
public:
BaseScopedReadWriteLock(RwMutex &locker)
: m_lock(locker)
{
}
virtual ~BaseScopedReadWriteLock() throw();
virtual ~BaseScopedReadWriteLock() throw();
void Release();
bool IsLocked() const { return m_IsLocked; }
};
void Release();
bool IsLocked() const { return m_IsLocked; }
};
// --------------------------------------------------------------------------------------
// ScopedReadLock / ScopedWriteLock
// --------------------------------------------------------------------------------------
class ScopedReadLock : public BaseScopedReadWriteLock
{
public:
ScopedReadLock( RwMutex& locker );
virtual ~ScopedReadLock() throw() {}
class ScopedReadLock : public BaseScopedReadWriteLock
{
public:
ScopedReadLock(RwMutex &locker);
virtual ~ScopedReadLock() throw() {}
void Acquire();
};
void Acquire();
};
class ScopedWriteLock : public BaseScopedReadWriteLock
{
public:
ScopedWriteLock( RwMutex& locker );
virtual ~ScopedWriteLock() throw() {}
class ScopedWriteLock : public BaseScopedReadWriteLock
{
public:
ScopedWriteLock(RwMutex &locker);
virtual ~ScopedWriteLock() throw() {}
void Acquire();
void Acquire();
protected:
ScopedWriteLock( RwMutex& locker, bool isTryLock );
};
protected:
ScopedWriteLock(RwMutex &locker, bool isTryLock);
};
}

View File

@ -23,8 +23,8 @@
// Microsoft Windows only macro, useful for freeing out COM objects:
#define safe_release( ptr ) \
((void) (( ( (ptr) != NULL ) && ((ptr)->Release(), !!0) ), (ptr) = NULL))
#define safe_release(ptr) \
((void)((((ptr) != NULL) && ((ptr)->Release(), !!0)), (ptr) = NULL))
// --------------------------------------------------------------------------------------
// SafeArray
@ -32,75 +32,75 @@
// Handy little class for allocating a resizable memory block, complete with exception
// error handling and automatic cleanup. A lightweight alternative to std::vector.
//
template< typename T >
template <typename T>
class SafeArray
{
DeclareNoncopyableObject(SafeArray);
DeclareNoncopyableObject(SafeArray);
public:
static const int DefaultChunkSize = 0x1000 * sizeof(T);
static const int DefaultChunkSize = 0x1000 * sizeof(T);
public:
wxString Name; // user-assigned block name
int ChunkSize;
wxString Name; // user-assigned block name
int ChunkSize;
protected:
T* m_ptr;
int m_size; // size of the allocation of memory
T *m_ptr;
int m_size; // size of the allocation of memory
protected:
SafeArray( const wxChar* name, T* allocated_mem, int initSize );
virtual T* _virtual_realloc( int newsize );
SafeArray(const wxChar *name, T *allocated_mem, int initSize);
virtual T *_virtual_realloc(int newsize);
// A safe array index fetcher. Asserts if the index is out of bounds (dev and debug
// builds only -- no bounds checking is done in release builds).
T* _getPtr( uint i ) const;
// A safe array index fetcher. Asserts if the index is out of bounds (dev and debug
// builds only -- no bounds checking is done in release builds).
T *_getPtr(uint i) const;
public:
virtual ~SafeArray() throw();
virtual ~SafeArray() throw();
explicit SafeArray( const wxChar* name=L"Unnamed" );
explicit SafeArray( int initialSize, const wxChar* name=L"Unnamed" );
void Dispose();
void ExactAlloc( int newsize );
void MakeRoomFor( int newsize )
{
if( newsize > m_size )
ExactAlloc( newsize );
}
explicit SafeArray(const wxChar *name = L"Unnamed");
explicit SafeArray(int initialSize, const wxChar *name = L"Unnamed");
bool IsDisposed() const { return (m_ptr==NULL); }
void Dispose();
void ExactAlloc(int newsize);
void MakeRoomFor(int newsize)
{
if (newsize > m_size)
ExactAlloc(newsize);
}
// Returns the size of the memory allocation, as according to the array type.
int GetLength() const { return m_size; }
// Returns the size of the memory allocation in bytes.
int GetSizeInBytes() const { return m_size * sizeof(T); }
bool IsDisposed() const { return (m_ptr == NULL); }
// Extends the containment area of the array. Extensions are performed
// in chunks.
void GrowBy( int items )
{
MakeRoomFor( m_size + ChunkSize + items + 1 );
}
// Returns the size of the memory allocation, as according to the array type.
int GetLength() const { return m_size; }
// Returns the size of the memory allocation in bytes.
int GetSizeInBytes() const { return m_size * sizeof(T); }
// Gets a pointer to the requested allocation index.
// DevBuilds : Generates assertion if the index is invalid.
T* GetPtr( uint idx=0 ) { return _getPtr( idx ); }
const T* GetPtr( uint idx=0 ) const { return _getPtr( idx ); }
// Extends the containment area of the array. Extensions are performed
// in chunks.
void GrowBy(int items)
{
MakeRoomFor(m_size + ChunkSize + items + 1);
}
// Gets a pointer to the element directly after the last element in the array.
// This is equivalent to doing GetPtr(GetLength()), except that this call *avoids*
// the out-of-bounds assertion check that typically occurs when you do that. :)
T* GetPtrEnd() { return &m_ptr[m_size]; }
const T* GetPtrEnd() const { return &m_ptr[m_size]; }
// Gets a pointer to the requested allocation index.
// DevBuilds : Generates assertion if the index is invalid.
T *GetPtr(uint idx = 0) { return _getPtr(idx); }
const T *GetPtr(uint idx = 0) const { return _getPtr(idx); }
// Gets an element of this memory allocation much as if it were an array.
// DevBuilds : Generates assertion if the index is invalid.
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); }
// Gets a pointer to the element directly after the last element in the array.
// This is equivalent to doing GetPtr(GetLength()), except that this call *avoids*
// the out-of-bounds assertion check that typically occurs when you do that. :)
T *GetPtrEnd() { return &m_ptr[m_size]; }
const T *GetPtrEnd() const { return &m_ptr[m_size]; }
virtual SafeArray<T>* Clone() const;
// Gets an element of this memory allocation much as if it were an array.
// DevBuilds : Generates assertion if the index is invalid.
T &operator[](int idx) { return *_getPtr((uint)idx); }
const T &operator[](int idx) const { return *_getPtr((uint)idx); }
virtual SafeArray<T> *Clone() const;
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -113,76 +113,76 @@ public:
// * Classes with copy constructors (copying is done using performance memcpy)
// * Classes with destructors (they're not called, sorry!)
//
template< typename T >
template <typename T>
class SafeList
{
DeclareNoncopyableObject(SafeList);
DeclareNoncopyableObject(SafeList);
public:
static const int DefaultChunkSize = 0x80 * sizeof(T);
static const int DefaultChunkSize = 0x80 * sizeof(T);
public:
wxString Name; // user-assigned block name
int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time.
wxString Name; // user-assigned block name
int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time.
protected:
T* m_ptr;
int m_allocsize; // size of the allocation of memory
uint m_length; // length of the array (active items, not buffer allocation)
T *m_ptr;
int m_allocsize; // size of the allocation of memory
uint m_length; // length of the array (active items, not buffer allocation)
protected:
virtual T* _virtual_realloc( int newsize );
void _MakeRoomFor_threshold( int newsize );
virtual T *_virtual_realloc(int newsize);
void _MakeRoomFor_threshold(int newsize);
T* _getPtr( uint i ) const;
T *_getPtr(uint i) const;
public:
virtual ~SafeList() throw();
explicit SafeList( const wxChar* name=L"Unnamed" );
explicit SafeList( int initialSize, const wxChar* name=L"Unnamed" );
virtual SafeList<T>* Clone() const;
virtual ~SafeList() throw();
explicit SafeList(const wxChar *name = L"Unnamed");
explicit SafeList(int initialSize, const wxChar *name = L"Unnamed");
virtual SafeList<T> *Clone() const;
void Remove( int index );
void MakeRoomFor( int blockSize );
void Remove(int index);
void MakeRoomFor(int blockSize);
T& New();
int Add( const T& src );
T& AddNew( const T& src );
T &New();
int Add(const T &src);
T &AddNew(const T &src);
// Returns the size of the list, as according to the array type. This includes
// mapped items only. The actual size of the allocation may differ.
int GetLength() const { return m_length; }
// Returns the size of the list, as according to the array type. This includes
// mapped items only. The actual size of the allocation may differ.
int GetLength() const { return m_length; }
// Returns the size of the list, in bytes. This includes mapped items only.
// The actual size of the allocation may differ.
int GetSizeInBytes() const { return m_length * sizeof(T); }
// Returns the size of the list, in bytes. This includes mapped items only.
// The actual size of the allocation may differ.
int GetSizeInBytes() const { return m_length * sizeof(T); }
void MatchLengthToAllocatedSize()
{
m_length = m_allocsize;
}
void MatchLengthToAllocatedSize()
{
m_length = m_allocsize;
}
void GrowBy( int items )
{
MakeRoomFor( m_length + ChunkSize + items + 1 );
}
void GrowBy(int items)
{
MakeRoomFor(m_length + ChunkSize + items + 1);
}
// Sets the item length to zero. Does not free memory allocations.
void Clear()
{
m_length = 0;
}
// Sets the item length to zero. Does not free memory allocations.
void Clear()
{
m_length = 0;
}
// Gets an element of this memory allocation much as if it were an array.
// DevBuilds : Generates assertion if the index is invalid.
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); }
// Gets an element of this memory allocation much as if it were an array.
// DevBuilds : Generates assertion if the index is invalid.
T &operator[](int idx) { return *_getPtr((uint)idx); }
const T &operator[](int idx) const { return *_getPtr((uint)idx); }
T* GetPtr() { return m_ptr; }
const T* GetPtr() const { return m_ptr; }
T *GetPtr() { return m_ptr; }
const T *GetPtr() const { return m_ptr; }
T& GetLast() { return m_ptr[m_length-1]; }
const T& GetLast() const{ return m_ptr[m_length-1]; }
T &GetLast() { return m_ptr[m_length - 1]; }
const T &GetLast() const { return m_ptr[m_length - 1]; }
};
// --------------------------------------------------------------------------------------
@ -192,25 +192,24 @@ public:
// exception-based error handling and automatic cleanup.
// This one supports aligned data allocations too!
template< typename T, uint Alignment >
template <typename T, uint Alignment>
class SafeAlignedArray : public SafeArray<T>
{
typedef SafeArray<T> _parent;
typedef SafeArray<T> _parent;
protected:
T* _virtual_realloc( int newsize );
T *_virtual_realloc(int newsize);
public:
using _parent::operator[];
using _parent::operator[];
virtual ~SafeAlignedArray() throw();
virtual ~SafeAlignedArray() throw();
explicit SafeAlignedArray( const wxChar* name=L"Unnamed" ) :
SafeArray<T>::SafeArray( name )
{
}
explicit SafeAlignedArray(const wxChar *name = L"Unnamed")
: SafeArray<T>::SafeArray(name)
{
}
explicit SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" );
virtual SafeAlignedArray<T,Alignment>* Clone() const;
explicit SafeAlignedArray(int initialSize, const wxChar *name = L"Unnamed");
virtual SafeAlignedArray<T, Alignment> *Clone() const;
};

View File

@ -21,104 +21,104 @@
// use its own memory allocation (with an aligned memory, for example).
// Throws:
// Exception::OutOfMemory if the allocated_mem pointer is NULL.
template< typename T >
SafeArray<T>::SafeArray( const wxChar* name, T* allocated_mem, int initSize )
: Name( name )
template <typename T>
SafeArray<T>::SafeArray(const wxChar *name, T *allocated_mem, int initSize)
: Name(name)
{
ChunkSize = DefaultChunkSize;
m_ptr = allocated_mem;
m_size = initSize;
ChunkSize = DefaultChunkSize;
m_ptr = allocated_mem;
m_size = initSize;
if( m_ptr == NULL )
throw Exception::OutOfMemory(name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ctor' [size=%d]", initSize));
if (m_ptr == NULL)
throw Exception::OutOfMemory(name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ctor' [size=%d]", initSize));
}
template< typename T >
T* SafeArray<T>::_virtual_realloc( int newsize )
template <typename T>
T *SafeArray<T>::_virtual_realloc(int newsize)
{
T* retval = (T*)((m_ptr == NULL) ?
malloc( newsize * sizeof(T) ) :
realloc( m_ptr, newsize * sizeof(T) )
);
if( IsDebugBuild && (retval != NULL))
{
// Zero everything out to 0xbaadf00d, so that its obviously uncleared
// to a debuggee
T *retval = (T *)((m_ptr == NULL) ?
malloc(newsize * sizeof(T)) :
realloc(m_ptr, newsize * sizeof(T)));
u32* fill = (u32*)&retval[m_size];
const u32* end = (u32*)((((uptr)&retval[newsize-1])-3) & ~0x3);
for( ; fill<end; ++fill ) *fill = 0xbaadf00d;
}
return retval;
if (IsDebugBuild && (retval != NULL)) {
// Zero everything out to 0xbaadf00d, so that its obviously uncleared
// to a debuggee
u32 *fill = (u32 *)&retval[m_size];
const u32 *end = (u32 *)((((uptr)&retval[newsize - 1]) - 3) & ~0x3);
for (; fill < end; ++fill)
*fill = 0xbaadf00d;
}
return retval;
}
template< typename T >
template <typename T>
SafeArray<T>::~SafeArray() throw()
{
safe_free( m_ptr );
safe_free(m_ptr);
}
template< typename T >
SafeArray<T>::SafeArray( const wxChar* name )
: Name( name )
template <typename T>
SafeArray<T>::SafeArray(const wxChar *name)
: Name(name)
{
ChunkSize = DefaultChunkSize;
m_ptr = NULL;
m_size = 0;
ChunkSize = DefaultChunkSize;
m_ptr = NULL;
m_size = 0;
}
template< typename T >
SafeArray<T>::SafeArray( int initialSize, const wxChar* name )
: Name( name )
template <typename T>
SafeArray<T>::SafeArray(int initialSize, const wxChar *name)
: Name(name)
{
ChunkSize = DefaultChunkSize;
m_ptr = (initialSize==0) ? NULL : (T*)malloc( initialSize * sizeof(T) );
m_size = initialSize;
ChunkSize = DefaultChunkSize;
m_ptr = (initialSize == 0) ? NULL : (T *)malloc(initialSize * sizeof(T));
m_size = initialSize;
if( (initialSize != 0) && (m_ptr == NULL) )
throw Exception::OutOfMemory(name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ctor' [size=%d]", initialSize));
if ((initialSize != 0) && (m_ptr == NULL))
throw Exception::OutOfMemory(name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ctor' [size=%d]", initialSize));
}
// Clears the contents of the array to zero, and frees all memory allocations.
template< typename T >
template <typename T>
void SafeArray<T>::Dispose()
{
m_size = 0;
safe_free( m_ptr );
m_size = 0;
safe_free(m_ptr);
}
template< typename T >
T* SafeArray<T>::_getPtr( uint i ) const
template <typename T>
T *SafeArray<T>::_getPtr(uint i) const
{
IndexBoundsAssumeDev( WX_STR(Name), i, m_size );
return &m_ptr[i];
IndexBoundsAssumeDev(WX_STR(Name), i, m_size);
return &m_ptr[i];
}
// reallocates the array to the explicit size. Can be used to shrink or grow an
// array, and bypasses the internal threshold growth indicators.
template< typename T >
void SafeArray<T>::ExactAlloc( int newsize )
template <typename T>
void SafeArray<T>::ExactAlloc(int newsize)
{
if( newsize == m_size ) return;
if (newsize == m_size)
return;
m_ptr = _virtual_realloc( newsize );
if( m_ptr == NULL )
throw Exception::OutOfMemory(Name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ExactAlloc' [oldsize=%d] [newsize=%d]", m_size, newsize));
m_ptr = _virtual_realloc(newsize);
if (m_ptr == NULL)
throw Exception::OutOfMemory(Name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ExactAlloc' [oldsize=%d] [newsize=%d]", m_size, newsize));
m_size = newsize;
m_size = newsize;
}
template< typename T >
SafeArray<T>* SafeArray<T>::Clone() const
template <typename T>
SafeArray<T> *SafeArray<T>::Clone() const
{
SafeArray<T>* retval = new SafeArray<T>( m_size );
memcpy( retval->GetPtr(), m_ptr, sizeof(T) * m_size );
return retval;
SafeArray<T> *retval = new SafeArray<T>(m_size);
memcpy(retval->GetPtr(), m_ptr, sizeof(T) * m_size);
return retval;
}
@ -126,164 +126,158 @@ SafeArray<T>* SafeArray<T>::Clone() const
// SafeAlignedArray<T> (implementations)
// --------------------------------------------------------------------------------------
template< typename T, uint Alignment >
T* SafeAlignedArray<T,Alignment>::_virtual_realloc( int newsize )
template <typename T, uint Alignment>
T *SafeAlignedArray<T, Alignment>::_virtual_realloc(int newsize)
{
return (T*)( ( this->m_ptr == NULL ) ?
_aligned_malloc( newsize * sizeof(T), Alignment ) :
pcsx2_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment, this->m_size * sizeof(T) )
);
return (T *)((this->m_ptr == NULL) ?
_aligned_malloc(newsize * sizeof(T), Alignment) :
pcsx2_aligned_realloc(this->m_ptr, newsize * sizeof(T), Alignment, this->m_size * sizeof(T)));
}
// Appends "(align: xx)" to the name of the allocation in devel builds.
// Maybe useful,maybe not... no harm in attaching it. :D
template< typename T, uint Alignment >
SafeAlignedArray<T,Alignment>::~SafeAlignedArray() throw()
template <typename T, uint Alignment>
SafeAlignedArray<T, Alignment>::~SafeAlignedArray() throw()
{
safe_aligned_free( this->m_ptr );
// mptr is set to null, so the parent class's destructor won't re-free it.
safe_aligned_free(this->m_ptr);
// mptr is set to null, so the parent class's destructor won't re-free it.
}
template< typename T, uint Alignment >
SafeAlignedArray<T,Alignment>::SafeAlignedArray( int initialSize, const wxChar* name ) :
SafeArray<T>::SafeArray(
name,
(T*)_aligned_malloc( initialSize * sizeof(T), Alignment ),
initialSize
)
template <typename T, uint Alignment>
SafeAlignedArray<T, Alignment>::SafeAlignedArray(int initialSize, const wxChar *name)
: SafeArray<T>::SafeArray(
name,
(T *)_aligned_malloc(initialSize * sizeof(T), Alignment),
initialSize)
{
}
template< typename T, uint Alignment >
SafeAlignedArray<T,Alignment>* SafeAlignedArray<T,Alignment>::Clone() const
template <typename T, uint Alignment>
SafeAlignedArray<T, Alignment> *SafeAlignedArray<T, Alignment>::Clone() const
{
SafeAlignedArray<T,Alignment>* retval = new SafeAlignedArray<T,Alignment>( this->m_size );
memcpy( retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size );
return retval;
SafeAlignedArray<T, Alignment> *retval = new SafeAlignedArray<T, Alignment>(this->m_size);
memcpy(retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size);
return retval;
}
// --------------------------------------------------------------------------------------
// SafeList<T> (implementations)
// --------------------------------------------------------------------------------------
template< typename T >
T* SafeList<T>::_virtual_realloc( int newsize )
template <typename T>
T *SafeList<T>::_virtual_realloc(int newsize)
{
return (T*)realloc( m_ptr, newsize * sizeof(T) );
return (T *)realloc(m_ptr, newsize * sizeof(T));
}
template< typename T >
template <typename T>
SafeList<T>::~SafeList() throw()
{
safe_free( m_ptr );
safe_free(m_ptr);
}
template< typename T >
SafeList<T>::SafeList( const wxChar* name )
: Name( name )
template <typename T>
SafeList<T>::SafeList(const wxChar *name)
: Name(name)
{
ChunkSize = DefaultChunkSize;
m_ptr = NULL;
m_allocsize = 0;
m_length = 0;
ChunkSize = DefaultChunkSize;
m_ptr = NULL;
m_allocsize = 0;
m_length = 0;
}
template< typename T >
SafeList<T>::SafeList( int initialSize, const wxChar* name )
: Name( name )
template <typename T>
SafeList<T>::SafeList(int initialSize, const wxChar *name)
: Name(name)
{
ChunkSize = DefaultChunkSize;
m_allocsize = initialSize;
m_length = 0;
m_ptr = (T*)malloc( initialSize * sizeof(T) );
ChunkSize = DefaultChunkSize;
m_allocsize = initialSize;
m_length = 0;
m_ptr = (T *)malloc(initialSize * sizeof(T));
if( m_ptr == NULL )
throw Exception::OutOfMemory(Name)
.SetDiagMsg(wxsFormat(L"called from 'SafeList::ctor' [length=%d]", m_length));
for( int i=0; i<m_allocsize; ++i )
{
new (&m_ptr[i]) T();
}
if (m_ptr == NULL)
throw Exception::OutOfMemory(Name)
.SetDiagMsg(wxsFormat(L"called from 'SafeList::ctor' [length=%d]", m_length));
for (int i = 0; i < m_allocsize; ++i) {
new (&m_ptr[i]) T();
}
}
template< typename T >
T* SafeList<T>::_getPtr( uint i ) const
template <typename T>
T *SafeList<T>::_getPtr(uint i) const
{
IndexBoundsAssumeDev( WX_STR(Name), i, m_length );
return &m_ptr[i];
IndexBoundsAssumeDev(WX_STR(Name), i, m_length);
return &m_ptr[i];
}
// Ensures that the allocation is large enough to fit data of the
// amount requested. The memory allocation is not resized smaller.
template< typename T >
void SafeList<T>::MakeRoomFor( int blockSize )
template <typename T>
void SafeList<T>::MakeRoomFor(int blockSize)
{
if( blockSize > m_allocsize )
{
const int newalloc = blockSize + ChunkSize;
m_ptr = _virtual_realloc( newalloc );
if( m_ptr == NULL )
throw Exception::OutOfMemory(Name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeList::MakeRoomFor' [oldlen=%d] [newlen=%d]", m_length, blockSize));
if (blockSize > m_allocsize) {
const int newalloc = blockSize + ChunkSize;
m_ptr = _virtual_realloc(newalloc);
if (m_ptr == NULL)
throw Exception::OutOfMemory(Name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeList::MakeRoomFor' [oldlen=%d] [newlen=%d]", m_length, blockSize));
for( ; m_allocsize<newalloc; ++m_allocsize )
{
new (&m_ptr[m_allocsize]) T();
}
}
for (; m_allocsize < newalloc; ++m_allocsize) {
new (&m_ptr[m_allocsize]) T();
}
}
}
// Appends an item to the end of the list and returns a handle to it.
template< typename T >
T& SafeList<T>::New()
template <typename T>
T &SafeList<T>::New()
{
_MakeRoomFor_threshold( m_length + 1 );
return m_ptr[m_length++];
_MakeRoomFor_threshold(m_length + 1);
return m_ptr[m_length++];
}
template< typename T >
int SafeList<T>::Add( const T& src )
template <typename T>
int SafeList<T>::Add(const T &src)
{
_MakeRoomFor_threshold( m_length + 1 );
m_ptr[m_length] = src;
return m_length++;
_MakeRoomFor_threshold(m_length + 1);
m_ptr[m_length] = src;
return m_length++;
}
// Same as Add, but returns the handle of the new object instead of it's array index.
template< typename T >
T& SafeList<T>::AddNew( const T& src )
template <typename T>
T &SafeList<T>::AddNew(const T &src)
{
_MakeRoomFor_threshold( m_length + 1 );
m_ptr[m_length] = src;
return m_ptr[m_length];
_MakeRoomFor_threshold(m_length + 1);
m_ptr[m_length] = src;
return m_ptr[m_length];
}
// Performs a standard array-copy removal of the given item. All items past the
// given item are copied over.
// DevBuilds : Generates assertion if the index is invalid.
template< typename T >
void SafeList<T>::Remove( int index )
template <typename T>
void SafeList<T>::Remove(int index)
{
IndexBoundsAssumeDev( Name.c_str(), index, m_length );
IndexBoundsAssumeDev(Name.c_str(), index, m_length);
int copylen = m_length - index;
if( copylen > 0 )
memcpy( &m_ptr[index], &m_ptr[index+1], copylen );
int copylen = m_length - index;
if (copylen > 0)
memcpy(&m_ptr[index], &m_ptr[index + 1], copylen);
}
template< typename T >
SafeList<T>* SafeList<T>::Clone() const
template <typename T>
SafeList<T> *SafeList<T>::Clone() const
{
SafeList<T>* retval = new SafeList<T>( m_length );
memcpy( retval->m_ptr, m_ptr, sizeof(T) * m_length );
return retval;
SafeList<T> *retval = new SafeList<T>(m_length);
memcpy(retval->m_ptr, m_ptr, sizeof(T) * m_length);
return retval;
}
template< typename T >
void SafeList<T>::_MakeRoomFor_threshold( int newsize )
template <typename T>
void SafeList<T>::_MakeRoomFor_threshold(int newsize)
{
MakeRoomFor( newsize + ChunkSize );
MakeRoomFor(newsize + ChunkSize);
}

View File

@ -27,43 +27,43 @@
// Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
// pointer to null after deallocation.
#define safe_delete( ptr ) \
((void) (delete (ptr)), (ptr) = NULL)
#define safe_delete(ptr) \
((void)(delete (ptr)), (ptr) = NULL)
#define safe_delete_array( ptr ) \
((void) (delete[] (ptr)), (ptr) = NULL)
#define safe_delete_array(ptr) \
((void)(delete[](ptr)), (ptr) = NULL)
// No checks for NULL -- wxWidgets says it's safe to skip NULL checks and it runs on
// No checks for NULL -- wxWidgets says it's safe to skip NULL checks and it runs on
// just about every compiler and libc implementation of any recentness.
#define safe_free( ptr ) \
( (void) (free( ptr ), !!0), (ptr) = NULL )
#define safe_free(ptr) \
((void)(free(ptr), !!0), (ptr) = NULL)
//((void) (( ( (ptr) != NULL ) && (free( ptr ), !!0) ), (ptr) = NULL))
#define safe_fclose( ptr ) \
((void) (( ( (ptr) != NULL ) && (fclose( ptr ), !!0) ), (ptr) = NULL))
#define safe_fclose(ptr) \
((void)((((ptr) != NULL) && (fclose(ptr), !!0)), (ptr) = NULL))
// Implementation note: all known implementations of _aligned_free check the pointer for
// NULL status (our implementation under GCC, and microsoft's under MSVC), so no need to
// do it here.
#define safe_aligned_free( ptr ) \
((void) ( _aligned_free( ptr ), (ptr) = NULL ))
#define safe_aligned_free(ptr) \
((void)(_aligned_free(ptr), (ptr) = NULL))
// aligned_malloc: Implement/declare linux equivalents here!
#if !defined(_MSC_VER)
extern void* __fastcall _aligned_malloc(size_t size, size_t align);
extern void* __fastcall pcsx2_aligned_realloc(void* handle, size_t new_size, size_t align, size_t old_size);
extern void _aligned_free(void* pmem);
extern void *__fastcall _aligned_malloc(size_t size, size_t align);
extern void *__fastcall pcsx2_aligned_realloc(void *handle, size_t new_size, size_t align, size_t old_size);
extern void _aligned_free(void *pmem);
#else
#define pcsx2_aligned_realloc(handle, new_size, align, old_size) \
_aligned_realloc(handle, new_size, align)
_aligned_realloc(handle, new_size, align)
#endif
// --------------------------------------------------------------------------------------
// pxDoOutOfMemory
// --------------------------------------------------------------------------------------
typedef void FnType_OutOfMemory( uptr blocksize );
typedef FnType_OutOfMemory* Fnptr_OutOfMemory;
typedef void FnType_OutOfMemory(uptr blocksize);
typedef FnType_OutOfMemory *Fnptr_OutOfMemory;
// This method is meant to be assigned by applications that link against pxWex. It is called
// (invoked) prior to most pxWex built-in memory/array classes throwing exceptions, and can be
@ -89,77 +89,78 @@ extern Fnptr_OutOfMemory pxDoOutOfMemory;
// destructing container for malloc. The entire class is almost completely dependency free,
// and thus can be included everywhere and anywhere without dependency hassles.
//
template< typename T >
template <typename T>
class BaseScopedAlloc
{
protected:
T* m_buffer;
uint m_size;
T *m_buffer;
uint m_size;
public:
BaseScopedAlloc()
{
m_buffer = NULL;
m_size = 0;
}
BaseScopedAlloc()
{
m_buffer = NULL;
m_size = 0;
}
virtual ~BaseScopedAlloc() throw()
{
//pxAssert(m_buffer==NULL);
}
virtual ~BaseScopedAlloc() throw()
{
//pxAssert(m_buffer==NULL);
}
public:
size_t GetSize() const { return m_size; }
size_t GetLength() const { return m_size; }
// Allocates the object to the specified size. If an existing allocation is in
// place, it is freed and replaced with the new allocation, and all data is lost.
// Parameter:
// newSize - size of the new allocation, in elements (not bytes!). If the specified
// size is 0, the the allocation is freed, same as calling Free().
virtual void Alloc( size_t newsize )=0;
size_t GetSize() const { return m_size; }
size_t GetLength() const { return m_size; }
// Re-sizes the allocation to the requested size, without any data loss.
// Parameter:
// newSize - size of the new allocation, in elements (not bytes!). If the specified
// size is 0, the the allocation is freed, same as calling Free().
virtual void Resize( size_t newsize )=0;
// Allocates the object to the specified size. If an existing allocation is in
// place, it is freed and replaced with the new allocation, and all data is lost.
// Parameter:
// newSize - size of the new allocation, in elements (not bytes!). If the specified
// size is 0, the the allocation is freed, same as calling Free().
virtual void Alloc(size_t newsize) = 0;
void Free()
{
Alloc( 0 );
}
// Makes enough room for the requested size. Existing data in the array is retained.
void MakeRoomFor( uint size )
{
if (size <= m_size) return;
Resize( size );
}
// Re-sizes the allocation to the requested size, without any data loss.
// Parameter:
// newSize - size of the new allocation, in elements (not bytes!). If the specified
// size is 0, the the allocation is freed, same as calling Free().
virtual void Resize(size_t newsize) = 0;
T* GetPtr( uint idx=0 ) const
{
#if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
#endif
return &m_buffer[idx];
}
void Free()
{
Alloc(0);
}
T& operator[]( uint idx )
{
#if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
#endif
return m_buffer[idx];
}
// Makes enough room for the requested size. Existing data in the array is retained.
void MakeRoomFor(uint size)
{
if (size <= m_size)
return;
Resize(size);
}
const T& operator[]( uint idx ) const
{
#if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
#endif
return m_buffer[idx];
}
T *GetPtr(uint idx = 0) const
{
#if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev("ScopedAlloc", idx, m_size);
#endif
return &m_buffer[idx];
}
T &operator[](uint idx)
{
#if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev("ScopedAlloc", idx, m_size);
#endif
return m_buffer[idx];
}
const T &operator[](uint idx) const
{
#if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev("ScopedAlloc", idx, m_size);
#endif
return m_buffer[idx];
}
};
// --------------------------------------------------------------------------------------
@ -171,43 +172,45 @@ public:
//
// See docs for BaseScopedAlloc for details and rationale.
//
template< typename T >
template <typename T>
class ScopedAlloc : public BaseScopedAlloc<T>
{
typedef BaseScopedAlloc<T> _parent;
typedef BaseScopedAlloc<T> _parent;
public:
ScopedAlloc( size_t size=0 ) : _parent()
{
Alloc(size);
}
ScopedAlloc(size_t size = 0)
: _parent()
{
Alloc(size);
}
virtual ~ScopedAlloc() throw()
{
safe_free(this->m_buffer);
}
virtual ~ScopedAlloc() throw()
{
safe_free(this->m_buffer);
}
virtual void Alloc( size_t newsize )
{
safe_free(this->m_buffer);
this->m_size = newsize;
if (!this->m_size) return;
virtual void Alloc(size_t newsize)
{
safe_free(this->m_buffer);
this->m_size = newsize;
if (!this->m_size)
return;
this->m_buffer = (T*)malloc( this->m_size * sizeof(T) );
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlloc");
}
this->m_buffer = (T *)malloc(this->m_size * sizeof(T));
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlloc");
}
virtual void Resize( size_t newsize )
{
this->m_size = newsize;
this->m_buffer = (T*)realloc(this->m_buffer, this->m_size * sizeof(T));
virtual void Resize(size_t newsize)
{
this->m_size = newsize;
this->m_buffer = (T *)realloc(this->m_buffer, this->m_size * sizeof(T));
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlloc::Resize");
}
using _parent::operator[];
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlloc::Resize");
}
using _parent::operator[];
};
// --------------------------------------------------------------------------------------
@ -219,41 +222,43 @@ public:
//
// See docs for BaseScopedAlloc for details and rationale.
//
template< typename T, uint align >
template <typename T, uint align>
class ScopedAlignedAlloc : public BaseScopedAlloc<T>
{
typedef BaseScopedAlloc<T> _parent;
typedef BaseScopedAlloc<T> _parent;
public:
ScopedAlignedAlloc( size_t size=0 ) : _parent()
{
Alloc(size);
}
virtual ~ScopedAlignedAlloc() throw()
{
safe_aligned_free(this->m_buffer);
}
ScopedAlignedAlloc(size_t size = 0)
: _parent()
{
Alloc(size);
}
virtual void Alloc( size_t newsize )
{
safe_aligned_free(this->m_buffer);
this->m_size = newsize;
if (!this->m_size) return;
virtual ~ScopedAlignedAlloc() throw()
{
safe_aligned_free(this->m_buffer);
}
this->m_buffer = (T*)_aligned_malloc( this->m_size * sizeof(T), align );
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc");
}
virtual void Alloc(size_t newsize)
{
safe_aligned_free(this->m_buffer);
this->m_size = newsize;
if (!this->m_size)
return;
virtual void Resize( size_t newsize )
{
this->m_buffer = (T*)pcsx2_aligned_realloc(this->m_buffer, newsize * sizeof(T), align, this->m_size * sizeof(T));
this->m_size = newsize;
this->m_buffer = (T *)_aligned_malloc(this->m_size * sizeof(T), align);
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc");
}
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize");
}
using _parent::operator[];
virtual void Resize(size_t newsize)
{
this->m_buffer = (T *)pcsx2_aligned_realloc(this->m_buffer, newsize * sizeof(T), align, this->m_size * sizeof(T));
this->m_size = newsize;
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize");
}
using _parent::operator[];
};

View File

@ -22,95 +22,96 @@ using Threading::ScopedLock;
// ScopedPtrMT
// --------------------------------------------------------------------------------------
template< typename T >
template <typename T>
class ScopedPtrMT
{
DeclareNoncopyableObject(ScopedPtrMT);
DeclareNoncopyableObject(ScopedPtrMT);
protected:
std::atomic<T*> m_ptr;
Threading::Mutex m_mtx;
std::atomic<T *> m_ptr;
Threading::Mutex m_mtx;
public:
typedef T element_type;
typedef T element_type;
wxEXPLICIT ScopedPtrMT(T * ptr = nullptr)
{
m_ptr = ptr;
}
wxEXPLICIT ScopedPtrMT(T *ptr = nullptr)
{
m_ptr = ptr;
}
~ScopedPtrMT() throw() { _Delete_unlocked(); }
~ScopedPtrMT() throw() { _Delete_unlocked(); }
ScopedPtrMT& Reassign(T * ptr = nullptr)
{
T* doh = m_ptr.exchange(ptr);
if ( ptr != doh ) delete doh;
return *this;
}
ScopedPtrMT &Reassign(T *ptr = nullptr)
{
T *doh = m_ptr.exchange(ptr);
if (ptr != doh)
delete doh;
return *this;
}
ScopedPtrMT& Delete() throw()
{
ScopedLock lock( m_mtx );
_Delete_unlocked();
}
ScopedPtrMT &Delete() throw()
{
ScopedLock lock(m_mtx);
_Delete_unlocked();
}
// Removes the pointer from scoped management, but does not delete!
// (ScopedPtr will be nullptr after this method)
T *DetachPtr()
{
ScopedLock lock( m_mtx );
// Removes the pointer from scoped management, but does not delete!
// (ScopedPtr will be nullptr after this method)
T *DetachPtr()
{
ScopedLock lock(m_mtx);
return m_ptr.exchange(nullptr);
}
return m_ptr.exchange(nullptr);
}
// Returns the managed pointer. Can return nullptr as a valid result if the ScopedPtrMT
// has no object in management.
T* GetPtr() const
{
return m_ptr;
}
// Returns the managed pointer. Can return nullptr as a valid result if the ScopedPtrMT
// has no object in management.
T *GetPtr() const
{
return m_ptr;
}
void SwapPtr(ScopedPtrMT& other)
{
ScopedLock lock( m_mtx );
m_ptr.exchange(other.m_ptr.exchange(m_ptr.load()));
T * const tmp = other.m_ptr;
other.m_ptr = m_ptr;
m_ptr = tmp;
}
void SwapPtr(ScopedPtrMT &other)
{
ScopedLock lock(m_mtx);
m_ptr.exchange(other.m_ptr.exchange(m_ptr.load()));
T *const tmp = other.m_ptr;
other.m_ptr = m_ptr;
m_ptr = tmp;
}
// ----------------------------------------------------------------------------
// ScopedPtrMT Operators
// ----------------------------------------------------------------------------
// I've decided to use the ATL's approach to pointer validity tests, opposed to
// the wx/boost approach (which uses some bizarre member method pointer crap, and can't
// allow the T* implicit casting.
// ----------------------------------------------------------------------------
// ScopedPtrMT Operators
// ----------------------------------------------------------------------------
// I've decided to use the ATL's approach to pointer validity tests, opposed to
// the wx/boost approach (which uses some bizarre member method pointer crap, and can't
// allow the T* implicit casting.
bool operator!() const throw()
{
return m_ptr.load() == nullptr;
}
bool operator!() const throw()
{
return m_ptr.load() == nullptr;
}
// Equality
bool operator==(T* pT) const throw()
{
return m_ptr == pT;
}
// Equality
bool operator==(T *pT) const throw()
{
return m_ptr == pT;
}
// Inequality
bool operator!=(T* pT) const throw()
{
return !operator==(pT);
}
// Inequality
bool operator!=(T *pT) const throw()
{
return !operator==(pT);
}
// Convenient assignment operator. ScopedPtrMT = nullptr will issue an automatic deletion
// of the managed pointer.
ScopedPtrMT& operator=( T* src )
{
return Reassign( src );
}
// Convenient assignment operator. ScopedPtrMT = nullptr will issue an automatic deletion
// of the managed pointer.
ScopedPtrMT &operator=(T *src)
{
return Reassign(src);
}
#if 0
#if 0
operator T*() const
{
return m_ptr;
@ -129,11 +130,11 @@ public:
pxAssert(m_ptr != nullptr);
return m_ptr;
}
#endif
#endif
protected:
void _Delete_unlocked() throw()
{
delete m_ptr.exchange(nullptr);
}
void _Delete_unlocked() throw()
{
delete m_ptr.exchange(nullptr);
}
};

View File

@ -22,10 +22,10 @@
#include <wx/tokenzr.h>
#if _WIN32
#define WX_STR(str) (str.wc_str())
#define WX_STR(str) (str.wc_str())
#else
// Stupid wx3.0 doesn't support c_str for vararg function
#define WX_STR(str) (static_cast<const char*>(str.c_str()))
#define WX_STR(str) (static_cast<const char *>(str.c_str()))
#endif
// --------------------------------------------------------------------------------------
@ -34,59 +34,59 @@
// Converts a string to UTF8 and provides an interface for getting its length.
class pxToUTF8
{
DeclareNoncopyableObject( pxToUTF8 );
DeclareNoncopyableObject(pxToUTF8);
protected:
wxCharBuffer m_result;
int m_length;
wxCharBuffer m_result;
int m_length;
public:
explicit pxToUTF8(const wxString& src)
: m_result( src.ToUTF8() )
{
m_length = -1;
}
explicit pxToUTF8(const wxString &src)
: m_result(src.ToUTF8())
{
m_length = -1;
}
size_t Length()
{
if( -1 == m_length )
m_length = strlen( m_result );
return m_length;
}
size_t Length()
{
if (-1 == m_length)
m_length = strlen(m_result);
return m_length;
}
void Convert( const wxString& src )
{
m_result = src.ToUTF8();
m_length = -1;
}
const char* data() const { return m_result; }
operator const char*() const
{
return m_result.data();
}
void Convert(const wxString &src)
{
m_result = src.ToUTF8();
m_length = -1;
}
const char *data() const { return m_result; }
operator const char *() const
{
return m_result.data();
}
};
extern void px_fputs( FILE* fp, const char* src );
extern void px_fputs(FILE *fp, const char *src);
// wxWidgets lacks one of its own...
extern const wxRect wxDefaultRect;
extern void SplitString( wxArrayString& dest, const wxString& src, const wxString& delims, wxStringTokenizerMode mode = wxTOKEN_RET_EMPTY_ALL );
extern wxString JoinString( const wxArrayString& src, const wxString& separator );
extern wxString JoinString( const wxChar** src, const wxString& separator );
extern void SplitString(wxArrayString &dest, const wxString &src, const wxString &delims, wxStringTokenizerMode mode = wxTOKEN_RET_EMPTY_ALL);
extern wxString JoinString(const wxArrayString &src, const wxString &separator);
extern wxString JoinString(const wxChar **src, const wxString &separator);
extern wxString ToString( const wxPoint& src, const wxString& separator=L"," );
extern wxString ToString( const wxSize& src, const wxString& separator=L"," );
extern wxString ToString( const wxRect& src, const wxString& separator=L"," );
extern wxString ToString(const wxPoint &src, const wxString &separator = L",");
extern wxString ToString(const wxSize &src, const wxString &separator = L",");
extern wxString ToString(const wxRect &src, const wxString &separator = L",");
extern bool TryParse( wxPoint& dest, const wxStringTokenizer& parts );
extern bool TryParse( wxSize& dest, const wxStringTokenizer& parts );
extern bool TryParse(wxPoint &dest, const wxStringTokenizer &parts);
extern bool TryParse(wxSize &dest, const wxStringTokenizer &parts);
extern bool TryParse( wxPoint& dest, const wxString& src, const wxPoint& defval=wxDefaultPosition, const wxString& separators=L",");
extern bool TryParse( wxSize& dest, const wxString& src, const wxSize& defval=wxDefaultSize, const wxString& separators=L",");
extern bool TryParse( wxRect& dest, const wxString& src, const wxRect& defval=wxDefaultRect, const wxString& separators=L",");
extern bool TryParse(wxPoint &dest, const wxString &src, const wxPoint &defval = wxDefaultPosition, const wxString &separators = L",");
extern bool TryParse(wxSize &dest, const wxString &src, const wxSize &defval = wxDefaultSize, const wxString &separators = L",");
extern bool TryParse(wxRect &dest, const wxString &src, const wxRect &defval = wxDefaultRect, const wxString &separators = L",");
// --------------------------------------------------------------------------------------
// ParsedAssignmentString
@ -104,11 +104,11 @@ extern bool TryParse( wxRect& dest, const wxString& src, const wxRect& defval=wx
//
struct ParsedAssignmentString
{
wxString lvalue;
wxString rvalue;
bool IsComment;
wxString lvalue;
wxString rvalue;
bool IsComment;
ParsedAssignmentString( const wxString& src );
ParsedAssignmentString(const wxString &src);
};
// ======================================================================================
@ -134,46 +134,46 @@ struct ParsedAssignmentString
typedef ScopedAlignedAlloc<char, 16> CharBufferType;
// --------------------------------------------------------------------------------------
// FastFormatAscii
// FastFormatAscii
// --------------------------------------------------------------------------------------
class FastFormatAscii
{
protected:
CharBufferType m_dest;
CharBufferType m_dest;
public:
FastFormatAscii();
~FastFormatAscii() throw();
FastFormatAscii& Write( const char* fmt, ... );
FastFormatAscii& WriteV( const char* fmt, va_list argptr );
FastFormatAscii();
~FastFormatAscii() throw();
FastFormatAscii &Write(const char *fmt, ...);
FastFormatAscii &WriteV(const char *fmt, va_list argptr);
void Clear();
bool IsEmpty() const;
void Clear();
bool IsEmpty() const;
const char* c_str() const { return m_dest.GetPtr(); }
operator const char*() const { return m_dest.GetPtr(); }
const char *c_str() const { return m_dest.GetPtr(); }
operator const char *() const { return m_dest.GetPtr(); }
const wxString GetString() const;
//operator wxString() const;
const wxString GetString() const;
//operator wxString() const;
FastFormatAscii& operator+=(const wxString& s)
{
Write( "%s", WX_STR(s) );
return *this;
}
FastFormatAscii &operator+=(const wxString &s)
{
Write("%s", WX_STR(s));
return *this;
}
FastFormatAscii& operator+=(const wxChar* psz )
{
Write( "%ls", psz );
return *this;
}
FastFormatAscii &operator+=(const wxChar *psz)
{
Write("%ls", psz);
return *this;
}
FastFormatAscii& operator+=(const char* psz )
{
Write( "%s", psz );
return *this;
}
FastFormatAscii &operator+=(const char *psz)
{
Write("%s", psz);
return *this;
}
};
// --------------------------------------------------------------------------------------
@ -182,57 +182,57 @@ public:
class FastFormatUnicode
{
protected:
CharBufferType m_dest;
uint m_Length;
CharBufferType m_dest;
uint m_Length;
public:
FastFormatUnicode();
~FastFormatUnicode() throw();
FastFormatUnicode();
~FastFormatUnicode() throw();
FastFormatUnicode& Write( const char* fmt, ... );
FastFormatUnicode& Write( const wxChar* fmt, ... );
FastFormatUnicode& Write( const wxString fmt, ... );
FastFormatUnicode& WriteV( const char* fmt, va_list argptr );
FastFormatUnicode& WriteV( const wxChar* fmt, va_list argptr );
FastFormatUnicode &Write(const char *fmt, ...);
FastFormatUnicode &Write(const wxChar *fmt, ...);
FastFormatUnicode &Write(const wxString fmt, ...);
FastFormatUnicode &WriteV(const char *fmt, va_list argptr);
FastFormatUnicode &WriteV(const wxChar *fmt, va_list argptr);
void Clear();
bool IsEmpty() const;
uint Length() const { return m_Length; }
void Clear();
bool IsEmpty() const;
uint Length() const { return m_Length; }
FastFormatUnicode& ToUpper();
FastFormatUnicode& ToLower();
FastFormatUnicode &ToUpper();
FastFormatUnicode &ToLower();
const wxChar* c_str() const { return (const wxChar*)m_dest.GetPtr(); }
operator const wxChar*() const { return (const wxChar*)m_dest.GetPtr(); }
operator wxString() const { return (const wxChar*)m_dest.GetPtr(); }
const wxChar *c_str() const { return (const wxChar *)m_dest.GetPtr(); }
operator const wxChar *() const { return (const wxChar *)m_dest.GetPtr(); }
operator wxString() const { return (const wxChar *)m_dest.GetPtr(); }
FastFormatUnicode& operator+=(const wxString& s)
{
Write( L"%s", WX_STR(s) );
return *this;
}
FastFormatUnicode &operator+=(const wxString &s)
{
Write(L"%s", WX_STR(s));
return *this;
}
FastFormatUnicode& operator+=(const wxChar* psz )
{
Write( L"%s", psz );
return *this;
}
FastFormatUnicode &operator+=(const wxChar *psz)
{
Write(L"%s", psz);
return *this;
}
FastFormatUnicode& operator+=(const char* psz );
FastFormatUnicode &operator+=(const char *psz);
};
extern bool pxParseAssignmentString( const wxString& src, wxString& ldest, wxString& rdest );
extern bool pxParseAssignmentString(const wxString &src, wxString &ldest, wxString &rdest);
#define pxsFmt FastFormatUnicode().Write
#define pxsFmtV FastFormatUnicode().WriteV
#define pxsFmt FastFormatUnicode().Write
#define pxsFmtV FastFormatUnicode().WriteV
#define pxsPtr(ptr) pxsFmt("0x%08X", (ptr)).c_str()
#define pxsPtr(ptr) pxsFmt("0x%08X", (ptr)).c_str()
extern wxString& operator+=(wxString& str1, const FastFormatUnicode& str2);
extern wxString operator+(const wxString& str1, const FastFormatUnicode& str2);
extern wxString operator+(const wxChar* str1, const FastFormatUnicode& str2);
extern wxString operator+(const FastFormatUnicode& str1, const wxString& str2);
extern wxString operator+(const FastFormatUnicode& str1, const wxChar* str2);
extern wxString &operator+=(wxString &str1, const FastFormatUnicode &str2);
extern wxString operator+(const wxString &str1, const FastFormatUnicode &str2);
extern wxString operator+(const wxChar *str1, const FastFormatUnicode &str2);
extern wxString operator+(const FastFormatUnicode &str1, const wxString &str2);
extern wxString operator+(const FastFormatUnicode &str1, const wxChar *str2);
//////////////////////////////////////////////////////////////////////////////////////////
@ -241,4 +241,4 @@ extern wxString operator+(const FastFormatUnicode& str1, const wxChar* str2);
// These functions are useful since they are ASCII always, even under Unicode. Typically
// even in a unicode app.
extern void ssappendf(std::string& dest, const char* format, ...);
extern void ssappendf(std::string &dest, const char *format, ...);

View File

@ -26,10 +26,10 @@
#include "Pcsx2Defs.h"
#include "TraceLog.h"
#undef Yield // release the burden of windows.h global namespace spam.
#undef Yield // release the burden of windows.h global namespace spam.
#define AffinityAssert_AllowFrom_MainUI() \
pxAssertMsg( wxThread::IsMain(), "Thread affinity violation: Call allowed from main thread only." )
pxAssertMsg(wxThread::IsMain(), "Thread affinity violation: Call allowed from main thread only.")
// --------------------------------------------------------------------------------------
// pxThreadLog / ConsoleLogSource_Threading
@ -37,22 +37,25 @@
class ConsoleLogSource_Threading : ConsoleLogSource
{
typedef ConsoleLogSource _parent;
typedef ConsoleLogSource _parent;
public:
using _parent::IsActive;
using _parent::IsActive;
ConsoleLogSource_Threading();
ConsoleLogSource_Threading();
bool Write( const wxString& thrname, const wxChar* msg ) {
return _parent::Write( wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg );
}
bool Warn( const wxString& thrname, const wxChar* msg ) {
return _parent::Warn( wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg );
}
bool Error( const wxString& thrname, const wxChar* msg ) {
return _parent::Error( wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg );
}
bool Write(const wxString &thrname, const wxChar *msg)
{
return _parent::Write(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg);
}
bool Warn(const wxString &thrname, const wxChar *msg)
{
return _parent::Warn(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg);
}
bool Error(const wxString &thrname, const wxChar *msg)
{
return _parent::Error(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg);
}
};
extern ConsoleLogSource_Threading pxConLog_Thread;
@ -69,79 +72,80 @@ extern ConsoleLogSource_Threading pxConLog_Thread;
//#define PCSX2_THREAD_LOCAL 0 // uncomment this line to force-disable native TLS (useful for testing TlsVariable on windows/linux)
#ifndef PCSX2_THREAD_LOCAL
# define PCSX2_THREAD_LOCAL 1
#define PCSX2_THREAD_LOCAL 1
#endif
class wxTimeSpan;
namespace Threading
{
class pxThread;
class RwMutex;
class pxThread;
class RwMutex;
extern void pxTestCancel();
extern pxThread* pxGetCurrentThread();
extern wxString pxGetCurrentThreadName();
extern u64 GetThreadCpuTime();
extern u64 GetThreadTicksPerSecond();
extern void pxTestCancel();
extern pxThread *pxGetCurrentThread();
extern wxString pxGetCurrentThreadName();
extern u64 GetThreadCpuTime();
extern u64 GetThreadTicksPerSecond();
// Yields the current thread and provides cancellation points if the thread is managed by
// pxThread. Unmanaged threads use standard Sleep.
extern void pxYield( int ms );
// Yields the current thread and provides cancellation points if the thread is managed by
// pxThread. Unmanaged threads use standard Sleep.
extern void pxYield(int ms);
}
namespace Exception
{
class BaseThreadError : public RuntimeError
{
DEFINE_EXCEPTION_COPYTORS( BaseThreadError, RuntimeError )
DEFINE_EXCEPTION_MESSAGES( BaseThreadError )
class BaseThreadError : public RuntimeError
{
DEFINE_EXCEPTION_COPYTORS(BaseThreadError, RuntimeError)
DEFINE_EXCEPTION_MESSAGES(BaseThreadError)
public:
Threading::pxThread* m_thread;
public:
Threading::pxThread *m_thread;
protected:
BaseThreadError() {
m_thread = NULL;
}
protected:
BaseThreadError()
{
m_thread = NULL;
}
public:
explicit BaseThreadError( Threading::pxThread* _thread )
{
m_thread = _thread;
m_message_diag = L"An unspecified thread-related error occurred (thread=%s)";
}
public:
explicit BaseThreadError(Threading::pxThread *_thread)
{
m_thread = _thread;
m_message_diag = L"An unspecified thread-related error occurred (thread=%s)";
}
explicit BaseThreadError( Threading::pxThread& _thread )
{
m_thread = &_thread;
m_message_diag = L"An unspecified thread-related error occurred (thread=%s)";
}
explicit BaseThreadError(Threading::pxThread &_thread)
{
m_thread = &_thread;
m_message_diag = L"An unspecified thread-related error occurred (thread=%s)";
}
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
Threading::pxThread& Thread();
const Threading::pxThread& Thread() const;
};
Threading::pxThread &Thread();
const Threading::pxThread &Thread() const;
};
class ThreadCreationError : public BaseThreadError
{
DEFINE_EXCEPTION_COPYTORS( ThreadCreationError, BaseThreadError )
class ThreadCreationError : public BaseThreadError
{
DEFINE_EXCEPTION_COPYTORS(ThreadCreationError, BaseThreadError)
public:
explicit ThreadCreationError( Threading::pxThread* _thread )
{
m_thread = _thread;
SetBothMsgs( L"Thread creation failure. An unspecified error occurred while trying to create the %s thread." );
}
public:
explicit ThreadCreationError(Threading::pxThread *_thread)
{
m_thread = _thread;
SetBothMsgs(L"Thread creation failure. An unspecified error occurred while trying to create the %s thread.");
}
explicit ThreadCreationError( Threading::pxThread& _thread )
{
m_thread = &_thread;
SetBothMsgs( L"Thread creation failure. An unspecified error occurred while trying to create the %s thread." );
}
};
explicit ThreadCreationError(Threading::pxThread &_thread)
{
m_thread = &_thread;
SetBothMsgs(L"Thread creation failure. An unspecified error occurred while trying to create the %s thread.");
}
};
}
@ -153,22 +157,22 @@ namespace Threading
// The following set of documented functions have Linux/Win32 specific implementations,
// which are found in WinThreads.cpp and LnxThreads.cpp
// Releases a timeslice to other threads.
extern void Timeslice();
// Releases a timeslice to other threads.
extern void Timeslice();
// For use in spin/wait loops.
extern void SpinWait();
// For use in spin/wait loops.
extern void SpinWait();
// Optional implementation to enable hires thread/process scheduler for the operating system.
// Needed by Windows, but might not be relevant to other platforms.
extern void EnableHiresScheduler();
extern void DisableHiresScheduler();
// Optional implementation to enable hires thread/process scheduler for the operating system.
// Needed by Windows, but might not be relevant to other platforms.
extern void EnableHiresScheduler();
extern void DisableHiresScheduler();
// sleeps the current thread for the given number of milliseconds.
extern void Sleep( int ms );
// sleeps the current thread for the given number of milliseconds.
extern void Sleep(int ms);
// pthread Cond is an evil api that is not suited for Pcsx2 needs.
// Let's not use it. Use mutexes and semaphores instead to create waits. (Air)
// pthread Cond is an evil api that is not suited for Pcsx2 needs.
// Let's not use it. Use mutexes and semaphores instead to create waits. (Air)
#if 0
struct WaitEvent
{
@ -194,181 +198,187 @@ namespace Threading
// If TryAcquire() returns true, you've locked the object and are *responsible* for unlocking
// it later.
//
class NonblockingMutex
{
protected:
std::atomic_flag val;
class NonblockingMutex
{
protected:
std::atomic_flag val;
public:
NonblockingMutex() { val.clear(); }
virtual ~NonblockingMutex() throw() {}
public:
NonblockingMutex() { val.clear(); }
virtual ~NonblockingMutex() throw() {}
bool TryAcquire() throw()
{
return !val.test_and_set();
}
bool TryAcquire() throw()
{
return !val.test_and_set();
}
// Can be done with a TryAcquire/Release but it is likely better to do it outside of the object
bool IsLocked()
{ pxAssertMsg(0, "IsLocked isn't supported for NonblockingMutex"); return false; }
// Can be done with a TryAcquire/Release but it is likely better to do it outside of the object
bool IsLocked()
{
pxAssertMsg(0, "IsLocked isn't supported for NonblockingMutex");
return false;
}
void Release()
{
val.clear();
}
};
void Release()
{
val.clear();
}
};
class Semaphore
{
protected:
class Semaphore
{
protected:
#ifdef __APPLE__
semaphore_t m_sema;
int m_counter;
semaphore_t m_sema;
int m_counter;
#else
sem_t m_sema;
sem_t m_sema;
#endif
public:
Semaphore();
virtual ~Semaphore() throw();
public:
Semaphore();
virtual ~Semaphore() throw();
void Reset();
void Post();
void Post( int multiple );
void Reset();
void Post();
void Post(int multiple);
void WaitWithoutYield();
bool WaitWithoutYield( const wxTimeSpan& timeout );
void WaitNoCancel();
void WaitNoCancel( const wxTimeSpan& timeout );
int Count();
void WaitWithoutYield();
bool WaitWithoutYield(const wxTimeSpan &timeout);
void WaitNoCancel();
void WaitNoCancel(const wxTimeSpan &timeout);
int Count();
void Wait();
bool Wait( const wxTimeSpan& timeout );
};
void Wait();
bool Wait(const wxTimeSpan &timeout);
};
class Mutex
{
protected:
pthread_mutex_t m_mutex;
class Mutex
{
protected:
pthread_mutex_t m_mutex;
public:
Mutex();
virtual ~Mutex() throw();
virtual bool IsRecursive() const { return false; }
public:
Mutex();
virtual ~Mutex() throw();
virtual bool IsRecursive() const { return false; }
void Recreate();
bool RecreateIfLocked();
void Detach();
void Recreate();
bool RecreateIfLocked();
void Detach();
void Acquire();
bool Acquire( const wxTimeSpan& timeout );
bool TryAcquire();
void Release();
void Acquire();
bool Acquire(const wxTimeSpan &timeout);
bool TryAcquire();
void Release();
void AcquireWithoutYield();
bool AcquireWithoutYield( const wxTimeSpan& timeout );
void AcquireWithoutYield();
bool AcquireWithoutYield(const wxTimeSpan &timeout);
void Wait();
bool Wait( const wxTimeSpan& timeout );
void WaitWithoutYield();
bool WaitWithoutYield( const wxTimeSpan& timeout );
void Wait();
bool Wait(const wxTimeSpan &timeout);
void WaitWithoutYield();
bool WaitWithoutYield(const wxTimeSpan &timeout);
protected:
// empty constructor used by MutexLockRecursive
Mutex( bool ) {}
};
protected:
// empty constructor used by MutexLockRecursive
Mutex(bool) {}
};
class MutexRecursive : public Mutex
{
public:
MutexRecursive();
virtual ~MutexRecursive() throw();
virtual bool IsRecursive() const { return true; }
};
class MutexRecursive : public Mutex
{
public:
MutexRecursive();
virtual ~MutexRecursive() throw();
virtual bool IsRecursive() const { return true; }
};
// --------------------------------------------------------------------------------------
// ScopedLock
// --------------------------------------------------------------------------------------
// Helper class for using Mutexes. Using this class provides an exception-safe (and
// generally clean) method of locking code inside a function or conditional block. The lock
// will be automatically released on any return or exit from the function.
//
// Const qualification note:
// ScopedLock takes const instances of the mutex, even though the mutex is modified
// by locking and unlocking. Two rationales:
//
// 1) when designing classes with accessors (GetString, GetValue, etc) that need mutexes,
// this class needs a const hack to allow those accessors to be const (which is typically
// *very* important).
//
// 2) The state of the Mutex is guaranteed to be unchanged when the calling function or
// scope exits, by any means. Only via manual calls to Release or Acquire does that
// change, and typically those are only used in very special circumstances of their own.
//
class ScopedLock
{
DeclareNoncopyableObject(ScopedLock);
// --------------------------------------------------------------------------------------
// ScopedLock
// --------------------------------------------------------------------------------------
// Helper class for using Mutexes. Using this class provides an exception-safe (and
// generally clean) method of locking code inside a function or conditional block. The lock
// will be automatically released on any return or exit from the function.
//
// Const qualification note:
// ScopedLock takes const instances of the mutex, even though the mutex is modified
// by locking and unlocking. Two rationales:
//
// 1) when designing classes with accessors (GetString, GetValue, etc) that need mutexes,
// this class needs a const hack to allow those accessors to be const (which is typically
// *very* important).
//
// 2) The state of the Mutex is guaranteed to be unchanged when the calling function or
// scope exits, by any means. Only via manual calls to Release or Acquire does that
// change, and typically those are only used in very special circumstances of their own.
//
class ScopedLock
{
DeclareNoncopyableObject(ScopedLock);
protected:
Mutex* m_lock;
bool m_IsLocked;
protected:
Mutex *m_lock;
bool m_IsLocked;
public:
virtual ~ScopedLock() throw();
explicit ScopedLock( const Mutex* locker=NULL );
explicit ScopedLock( const Mutex& locker );
void AssignAndLock( const Mutex& locker );
void AssignAndLock( const Mutex* locker );
public:
virtual ~ScopedLock() throw();
explicit ScopedLock(const Mutex *locker = NULL);
explicit ScopedLock(const Mutex &locker);
void AssignAndLock(const Mutex &locker);
void AssignAndLock(const Mutex *locker);
void Assign( const Mutex& locker );
void Assign( const Mutex* locker );
void Assign(const Mutex &locker);
void Assign(const Mutex *locker);
void Release();
void Acquire();
void Release();
void Acquire();
bool IsLocked() const { return m_IsLocked; }
bool IsLocked() const { return m_IsLocked; }
protected:
// Special constructor used by ScopedTryLock
ScopedLock( const Mutex& locker, bool isTryLock );
};
protected:
// Special constructor used by ScopedTryLock
ScopedLock(const Mutex &locker, bool isTryLock);
};
class ScopedTryLock : public ScopedLock
{
public:
ScopedTryLock( const Mutex& locker ) : ScopedLock( locker, true ) { }
virtual ~ScopedTryLock() throw() {}
bool Failed() const { return !m_IsLocked; }
};
class ScopedTryLock : public ScopedLock
{
public:
ScopedTryLock(const Mutex &locker)
: ScopedLock(locker, true)
{
}
virtual ~ScopedTryLock() throw() {}
bool Failed() const { return !m_IsLocked; }
};
// --------------------------------------------------------------------------------------
// ScopedNonblockingLock
// --------------------------------------------------------------------------------------
// A ScopedTryLock branded for use with Nonblocking mutexes. See ScopedTryLock for details.
//
class ScopedNonblockingLock
{
DeclareNoncopyableObject(ScopedNonblockingLock);
class ScopedNonblockingLock
{
DeclareNoncopyableObject(ScopedNonblockingLock);
protected:
NonblockingMutex& m_lock;
bool m_IsLocked;
protected:
NonblockingMutex &m_lock;
bool m_IsLocked;
public:
ScopedNonblockingLock( NonblockingMutex& locker ) :
m_lock( locker )
, m_IsLocked( m_lock.TryAcquire() )
{
}
public:
ScopedNonblockingLock(NonblockingMutex &locker)
: m_lock(locker)
, m_IsLocked(m_lock.TryAcquire())
{
}
virtual ~ScopedNonblockingLock() throw()
{
if( m_IsLocked )
m_lock.Release();
}
virtual ~ScopedNonblockingLock() throw()
{
if (m_IsLocked)
m_lock.Release();
}
bool Failed() const { return !m_IsLocked; }
};
bool Failed() const { return !m_IsLocked; }
};
// --------------------------------------------------------------------------------------
// ScopedLockBool
@ -377,26 +387,30 @@ namespace Threading
// Note that the isLockedBool should only be used as an indicator for the locked status,
// and not actually depended on for thread synchronization...
struct ScopedLockBool {
ScopedLock m_lock;
std::atomic<bool>& m_bool;
struct ScopedLockBool
{
ScopedLock m_lock;
std::atomic<bool> &m_bool;
ScopedLockBool(Mutex& mutexToLock, std::atomic<bool>& isLockedBool)
: m_lock(mutexToLock),
m_bool(isLockedBool) {
m_bool.store(m_lock.IsLocked(), std::memory_order_relaxed);
}
virtual ~ScopedLockBool() throw() {
m_bool.store(false, std::memory_order_relaxed);
}
void Acquire() {
m_lock.Acquire();
m_bool.store(m_lock.IsLocked(), std::memory_order_relaxed);
}
void Release() {
m_bool.store(false, std::memory_order_relaxed);
m_lock.Release();
}
};
ScopedLockBool(Mutex &mutexToLock, std::atomic<bool> &isLockedBool)
: m_lock(mutexToLock)
, m_bool(isLockedBool)
{
m_bool.store(m_lock.IsLocked(), std::memory_order_relaxed);
}
virtual ~ScopedLockBool() throw()
{
m_bool.store(false, std::memory_order_relaxed);
}
void Acquire()
{
m_lock.Acquire();
m_bool.store(m_lock.IsLocked(), std::memory_order_relaxed);
}
void Release()
{
m_bool.store(false, std::memory_order_relaxed);
m_lock.Release();
}
};
}

View File

@ -22,32 +22,31 @@ wxDECLARE_EVENT(pxEvt_ThreadedTaskComplete, wxCommandEvent);
namespace Threading
{
// --------------------------------------------------------------------------------------
// WaitForTaskDialog
// --------------------------------------------------------------------------------------
// This dialog is displayed whenever the main thread is recursively waiting on multiple
// mutexes or semaphores. wxwidgets does not support recursive yielding to pending events
// but it *does* support opening a modal dialog, which disables the interface (preventing
// the user from starting additional actions), and processes messages (allowing the system
// to continue to manage threads and process logging).
//
class WaitForTaskDialog : public wxDialogWithHelpers
{
DECLARE_DYNAMIC_CLASS_NO_COPY(WaitForTaskDialog)
// --------------------------------------------------------------------------------------
// WaitForTaskDialog
// --------------------------------------------------------------------------------------
// This dialog is displayed whenever the main thread is recursively waiting on multiple
// mutexes or semaphores. wxwidgets does not support recursive yielding to pending events
// but it *does* support opening a modal dialog, which disables the interface (preventing
// the user from starting additional actions), and processes messages (allowing the system
// to continue to manage threads and process logging).
//
class WaitForTaskDialog : public wxDialogWithHelpers
{
DECLARE_DYNAMIC_CLASS_NO_COPY(WaitForTaskDialog)
typedef wxDialogWithHelpers _parent;
typedef wxDialogWithHelpers _parent;
protected:
SynchronousActionState m_sync;
protected:
SynchronousActionState m_sync;
public:
WaitForTaskDialog( const wxString& title=wxEmptyString, const wxString& heading=wxEmptyString );
virtual ~WaitForTaskDialog() throw() {}
virtual int ShowModal();
protected:
void OnTaskComplete( wxCommandEvent& evt );
//void OnTimer( wxTimerEvent& evt );
};
public:
WaitForTaskDialog(const wxString &title = wxEmptyString, const wxString &heading = wxEmptyString);
virtual ~WaitForTaskDialog() throw() {}
virtual int ShowModal();
protected:
void OnTaskComplete(wxCommandEvent &evt);
//void OnTimer( wxTimerEvent& evt );
};
}

View File

@ -18,9 +18,9 @@
#include "Threading.h"
#if PCSX2_THREAD_LOCAL
# define DeclareTls(x) __threadlocal x
#define DeclareTls(x) __threadlocal x
#else
# define DeclareTls(x) Threading::TlsVariable<x>
#define DeclareTls(x) Threading::TlsVariable<x>
#endif
namespace Threading
@ -38,152 +38,153 @@ namespace Threading
// result in repeated calls to pthread_getspecific. (if the function inlines then it
// should actually optimize well enough, but I doubt it does).
//
template< typename T >
template <typename T>
class BaseTlsVariable
{
DeclareNoncopyableObject(BaseTlsVariable<T>);
DeclareNoncopyableObject(BaseTlsVariable<T>);
protected:
pthread_key_t m_thread_key;
bool m_IsDisposed;
pthread_key_t m_thread_key;
bool m_IsDisposed;
public:
BaseTlsVariable();
BaseTlsVariable();
virtual ~BaseTlsVariable() throw()
{
Dispose();
}
virtual ~BaseTlsVariable() throw()
{
Dispose();
}
T* GetPtr() const;
T& GetRef() const { return *GetPtr(); }
T *GetPtr() const;
T &GetRef() const { return *GetPtr(); }
operator T&() const { return GetRef(); }
T* operator->() const { return GetPtr(); }
operator T &() const { return GetRef(); }
T *operator->() const { return GetPtr(); }
void Dispose()
{
if (!m_IsDisposed)
{
m_IsDisposed = true;
KillKey();
}
}
void Dispose()
{
if (!m_IsDisposed) {
m_IsDisposed = true;
KillKey();
}
}
protected:
void CreateKey();
void KillKey();
void CreateKey();
void KillKey();
virtual void CreateInstance( T* result ) const
{
new (result) T();
}
virtual void CreateInstance(T *result) const
{
new (result) T();
}
static void _aligned_delete_and_free( void* ptr )
{
if (!ptr) return;
((T*)ptr)->~T();
_aligned_free(ptr);
}
static void _aligned_delete_and_free(void *ptr)
{
if (!ptr)
return;
((T *)ptr)->~T();
_aligned_free(ptr);
}
};
template< typename T >
template <typename T>
class TlsVariable : public BaseTlsVariable<T>
{
DeclareNoncopyableObject(TlsVariable<T>);
DeclareNoncopyableObject(TlsVariable<T>);
protected:
T m_initval;
T m_initval;
public:
TlsVariable() {}
TlsVariable( const T& initval )
: m_initval(initval) { }
TlsVariable() {}
TlsVariable(const T &initval)
: m_initval(initval)
{
}
// This is needed; The C++ standard likes making life suck for programmers.
using BaseTlsVariable<T>::GetRef;
// This is needed; The C++ standard likes making life suck for programmers.
using BaseTlsVariable<T>::GetRef;
virtual ~TlsVariable() throw()
{
// disable the parent cleanup. This leaks memory blocks, but its necessary because
// TLS is expected to be persistent until the very end of execution on the main thread.
// Killing the pthread_key at all will lead to the console logger death, etc.
// DON'T REMOVE this->, the "official"[ly stupid] C++ standard requires it because of its
// insistence that variables be looked up during initial template parsing and not during
// instantiation.
this->m_IsDisposed = true;
}
virtual ~TlsVariable() throw()
{
// disable the parent cleanup. This leaks memory blocks, but its necessary because
// TLS is expected to be persistent until the very end of execution on the main thread.
// Killing the pthread_key at all will lead to the console logger death, etc.
TlsVariable<T>& operator=( const T& src )
{
GetRef() = src;
return *this;
}
// DON'T REMOVE this->, the "official"[ly stupid] C++ standard requires it because of its
// insistence that variables be looked up during initial template parsing and not during
// instantiation.
this->m_IsDisposed = true;
}
bool operator==( const T& src ) const { return GetRef() == src; }
bool operator!=( const T& src ) const { return GetRef() != src; }
bool operator>( const T& src ) const { return GetRef() > src; }
bool operator<( const T& src ) const { return GetRef() < src; }
bool operator>=( const T& src ) const { return GetRef() >= src; }
bool operator<=( const T& src ) const { return GetRef() <= src; }
TlsVariable<T> &operator=(const T &src)
{
GetRef() = src;
return *this;
}
T operator+( const T& src ) const { return GetRef() + src; }
T operator-( const T& src ) const { return GetRef() - src; }
bool operator==(const T &src) const { return GetRef() == src; }
bool operator!=(const T &src) const { return GetRef() != src; }
bool operator>(const T &src) const { return GetRef() > src; }
bool operator<(const T &src) const { return GetRef() < src; }
bool operator>=(const T &src) const { return GetRef() >= src; }
bool operator<=(const T &src) const { return GetRef() <= src; }
T operator+(const T &src) const { return GetRef() + src; }
T operator-(const T &src) const { return GetRef() - src; }
void operator+=(const T &src) { GetRef() += src; }
void operator-=(const T &src) { GetRef() -= src; }
void operator+=( const T& src ) { GetRef() += src; }
void operator-=( const T& src ) { GetRef() -= src; }
protected:
virtual void CreateInstance( T* result ) const
{
new (result) T(m_initval);
}
virtual void CreateInstance(T *result) const
{
new (result) T(m_initval);
}
};
};
template< typename T >
template <typename T>
Threading::BaseTlsVariable<T>::BaseTlsVariable()
{
m_IsDisposed = false;
CreateKey();
m_IsDisposed = false;
CreateKey();
}
template< typename T >
template <typename T>
void Threading::BaseTlsVariable<T>::KillKey()
{
if (!m_thread_key) return;
if (!m_thread_key)
return;
// Delete the handle for the current thread (which should always be the main/UI thread!)
// This is needed because pthreads does *not* clean up the dangling objects when you delete
// the key. The TLS for the process main thread will only be deleted when the process
// ends; which is too damn late (it shows up int he leaked memory blocks).
// Delete the handle for the current thread (which should always be the main/UI thread!)
// This is needed because pthreads does *not* clean up the dangling objects when you delete
// the key. The TLS for the process main thread will only be deleted when the process
// ends; which is too damn late (it shows up int he leaked memory blocks).
BaseTlsVariable<T>::_aligned_delete_and_free( pthread_getspecific(m_thread_key) );
BaseTlsVariable<T>::_aligned_delete_and_free(pthread_getspecific(m_thread_key));
pthread_key_delete( m_thread_key );
m_thread_key = 0;
pthread_key_delete(m_thread_key);
m_thread_key = 0;
}
template< typename T >
T* Threading::BaseTlsVariable<T>::GetPtr() const
template <typename T>
T *Threading::BaseTlsVariable<T>::GetPtr() const
{
T* result = (T*)pthread_getspecific( m_thread_key );
if( result == NULL )
{
pthread_setspecific( m_thread_key, result = (T*)_aligned_malloc(sizeof(T), 16) );
CreateInstance(result);
if( result == NULL )
throw Exception::OutOfMemory( L"thread local storage variable instance" );
}
return result;
T *result = (T *)pthread_getspecific(m_thread_key);
if (result == NULL) {
pthread_setspecific(m_thread_key, result = (T *)_aligned_malloc(sizeof(T), 16));
CreateInstance(result);
if (result == NULL)
throw Exception::OutOfMemory(L"thread local storage variable instance");
}
return result;
}
template< typename T >
template <typename T>
void Threading::BaseTlsVariable<T>::CreateKey()
{
if( 0 != pthread_key_create(&m_thread_key, BaseTlsVariable<T>::_aligned_delete_and_free) )
{
pxFailRel( "Thread Local Storage Error: key creation failed. This will most likely lead to a rapid application crash." );
}
if (0 != pthread_key_create(&m_thread_key, BaseTlsVariable<T>::_aligned_delete_and_free)) {
pxFailRel("Thread Local Storage Error: key creation failed. This will most likely lead to a rapid application crash.");
}
}

View File

@ -29,20 +29,20 @@
//
struct TraceLogDescriptor
{
// short name, alphanumerics only: used for saving/loading options.
const wxChar* ShortName;
// short name, alphanumerics only: used for saving/loading options.
const wxChar *ShortName;
// Standard UI name for this log source. Used in menus, options dialogs.
const wxChar* Name;
// Standard UI name for this log source. Used in menus, options dialogs.
const wxChar *Name;
// Length description for use as a tooltip or menu item description.
const wxChar* Description;
// Length description for use as a tooltip or menu item description.
const wxChar *Description;
wxString GetShortName() const
{
pxAssumeDev(Name, "Tracelog descriptors require a valid name!");
return ShortName ? ShortName : Name;
}
wxString GetShortName() const
{
pxAssumeDev(Name, "Tracelog descriptors require a valid name!");
return ShortName ? ShortName : Name;
}
};
// --------------------------------------------------------------------------------------
@ -62,52 +62,55 @@ struct TraceLogDescriptor
// check is done top-level, the parameters' calculations can be skipped. If the IsActive()
// check is done internally as part of the Write/Format calls, all parameters have to be
// resolved regardless of if the log is actually active.
//
//
class BaseTraceLogSource
{
protected:
const TraceLogDescriptor* m_Descriptor;
const TraceLogDescriptor *m_Descriptor;
public:
// Indicates if the user has enabled this specific log. This boolean only represents
// the configured status of this log, and does *NOT* actually mean the log is active
// even when TRUE. Because many tracelogs have master enablers that act on a group
// of logs, logging checks should always use IsActive() instead to determine if a log
// should be processed or not.
bool Enabled;
// Indicates if the user has enabled this specific log. This boolean only represents
// the configured status of this log, and does *NOT* actually mean the log is active
// even when TRUE. Because many tracelogs have master enablers that act on a group
// of logs, logging checks should always use IsActive() instead to determine if a log
// should be processed or not.
bool Enabled;
protected:
BaseTraceLogSource() : m_Descriptor(NULL), Enabled(false) {}
BaseTraceLogSource()
: m_Descriptor(NULL)
, Enabled(false)
{
}
public:
TraceLog_ImplementBaseAPI(BaseTraceLogSource)
TraceLog_ImplementBaseAPI(BaseTraceLogSource)
BaseTraceLogSource( const TraceLogDescriptor* desc )
{
pxAssumeDev( desc, "Trace logs must have a valid (non-NULL) descriptor." );
Enabled = false;
m_Descriptor = desc;
}
BaseTraceLogSource(const TraceLogDescriptor *desc)
{
pxAssumeDev(desc, "Trace logs must have a valid (non-NULL) descriptor.");
Enabled = false;
m_Descriptor = desc;
}
// Provides a categorical identifier, typically in "group.subgroup.subgroup" form.
// (use periods in favor of colons, since they do not require escape characters when
// written to ini/config files).
virtual wxString GetCategory() const { return wxEmptyString; }
// Provides a categorical identifier, typically in "group.subgroup.subgroup" form.
// (use periods in favor of colons, since they do not require escape characters when
// written to ini/config files).
virtual wxString GetCategory() const { return wxEmptyString; }
// This method should be used to determine if a log should be generated or not.
// See the class overview comments for details on how and why this method should
// be used.
virtual bool IsActive() const { return Enabled; }
// This method should be used to determine if a log should be generated or not.
// See the class overview comments for details on how and why this method should
// be used.
virtual bool IsActive() const { return Enabled; }
virtual wxString GetShortName() const { return m_Descriptor->GetShortName(); }
virtual const wxChar* GetName() const { return m_Descriptor->Name; }
virtual const wxChar* GetDescription() const
{
return (m_Descriptor->Description!=NULL) ? pxGetTranslation(m_Descriptor->Description) : wxEmptyString;
}
virtual bool HasDescription() const { return m_Descriptor->Description != NULL;}
virtual wxString GetShortName() const { return m_Descriptor->GetShortName(); }
virtual const wxChar *GetName() const { return m_Descriptor->Name; }
virtual const wxChar *GetDescription() const
{
return (m_Descriptor->Description != NULL) ? pxGetTranslation(m_Descriptor->Description) : wxEmptyString;
}
virtual bool HasDescription() const { return m_Descriptor->Description != NULL; }
};
// --------------------------------------------------------------------------------------
@ -119,32 +122,32 @@ public:
class TextFileTraceLog : public BaseTraceLogSource
{
public:
TextFileTraceLog( const TraceLogDescriptor* desc )
: BaseTraceLogSource( desc )
{
}
TextFileTraceLog(const TraceLogDescriptor *desc)
: BaseTraceLogSource(desc)
{
}
bool Write( const char* fmt, ... ) const
{
va_list list;
va_start( list, fmt );
WriteV( fmt, list );
va_end( list );
bool Write(const char *fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(fmt, list);
va_end(list);
return false;
}
return false;
}
bool WriteV( const char *fmt, va_list list ) const
{
FastFormatAscii ascii;
ApplyPrefix(ascii);
ascii.WriteV( fmt, list );
DoWrite( ascii );
return false;
}
bool WriteV(const char *fmt, va_list list) const
{
FastFormatAscii ascii;
ApplyPrefix(ascii);
ascii.WriteV(fmt, list);
DoWrite(ascii);
return false;
}
virtual void ApplyPrefix( FastFormatAscii& ascii ) const {}
virtual void DoWrite( const char* fmt ) const=0;
virtual void ApplyPrefix(FastFormatAscii &ascii) const {}
virtual void DoWrite(const char *fmt) const = 0;
};
// --------------------------------------------------------------------------------------
@ -156,128 +159,130 @@ public:
class ConsoleLogSource : public BaseTraceLogSource
{
public:
ConsoleColors DefaultColor;
ConsoleColors DefaultColor;
protected:
ConsoleLogSource() : DefaultColor(Color_Gray) {}
ConsoleLogSource()
: DefaultColor(Color_Gray)
{
}
public:
ConsoleLog_ImplementBaseAPI(ConsoleLogSource)
ConsoleLog_ImplementBaseAPI(ConsoleLogSource)
ConsoleLogSource( const TraceLogDescriptor* desc, ConsoleColors defaultColor = Color_Gray )
: BaseTraceLogSource(desc)
{
DefaultColor = defaultColor;
}
ConsoleLogSource(const TraceLogDescriptor *desc, ConsoleColors defaultColor = Color_Gray)
: BaseTraceLogSource(desc)
{
DefaultColor = defaultColor;
}
// Writes to the console using the source's default color. Note that the source's default
// color will always be used, thus ConsoleColorScope() will not be effectual unless the
// console's default color is Color_Default.
bool Write( const char* fmt, ... ) const
{
va_list list;
va_start( list, fmt );
WriteV( fmt, list );
va_end( list );
// Writes to the console using the source's default color. Note that the source's default
// color will always be used, thus ConsoleColorScope() will not be effectual unless the
// console's default color is Color_Default.
bool Write(const char *fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(fmt, list);
va_end(list);
return false;
}
return false;
}
bool Write( const wxChar* fmt, ... ) const
{
va_list list;
va_start( list, fmt );
WriteV( fmt, list );
va_end( list );
bool Write(const wxChar *fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(fmt, list);
va_end(list);
return false;
}
return false;
}
bool Write( const wxString fmt, ... ) const
{
va_list list;
va_start( list, fmt );
WriteV( fmt.wx_str(), list );
va_end( list );
bool Write(const wxString fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(fmt.wx_str(), list);
va_end(list);
return false;
}
return false;
}
// Writes to the console using the specified color. This overrides the default color setting
// for this log.
bool Write( ConsoleColors color, const char* fmt, ... ) const
{
va_list list;
va_start( list, fmt );
WriteV( color, fmt, list );
va_end( list );
// Writes to the console using the specified color. This overrides the default color setting
// for this log.
bool Write(ConsoleColors color, const char *fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(color, fmt, list);
va_end(list);
return false;
}
return false;
}
bool Write( ConsoleColors color, const wxChar* fmt, ... ) const
{
va_list list;
va_start( list, fmt );
WriteV( color, fmt, list );
va_end( list );
bool Write(ConsoleColors color, const wxChar *fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(color, fmt, list);
va_end(list);
return false;
}
return false;
}
// Writes to the console using bold yellow text -- overrides the log source's default
// color settings.
bool Warn( const wxChar* fmt, ... ) const
{
va_list list;
va_start( list, fmt );
WriteV( Color_StrongYellow, fmt, list );
va_end( list );
// Writes to the console using bold yellow text -- overrides the log source's default
// color settings.
bool Warn(const wxChar *fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(Color_StrongYellow, fmt, list);
va_end(list);
return false;
}
return false;
}
bool Warn( const wxString fmt, ... ) const
{
va_list list;
va_start( list, fmt );
WriteV( Color_StrongYellow, fmt.wx_str(), list );
va_end( list );
bool Warn(const wxString fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(Color_StrongYellow, fmt.wx_str(), list);
va_end(list);
return false;
}
return false;
}
// Writes to the console using bold red text -- overrides the log source's default
// color settings.
bool Error( const wxChar* fmt, ... ) const
{
va_list list;
va_start( list, fmt );
WriteV( Color_StrongRed, fmt, list );
va_end( list );
// Writes to the console using bold red text -- overrides the log source's default
// color settings.
bool Error(const wxChar *fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(Color_StrongRed, fmt, list);
va_end(list);
return false;
}
return false;
}
bool Error( const wxString fmt, ... ) const
{
va_list list;
va_start( list, fmt );
WriteV( Color_StrongRed, fmt.wx_str(), list );
va_end( list );
bool Error(const wxString fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(Color_StrongRed, fmt.wx_str(), list);
va_end(list);
return false;
}
return false;
}
bool WriteV( const char *fmt, va_list list ) const;
bool WriteV( const wxChar *fmt, va_list list ) const;
bool WriteV(const char *fmt, va_list list) const;
bool WriteV(const wxChar *fmt, va_list list) const;
bool WriteV( ConsoleColors color, const char *fmt, va_list list ) const;
bool WriteV( ConsoleColors color, const wxChar *fmt, va_list list ) const;
bool WriteV(ConsoleColors color, const char *fmt, va_list list) const;
bool WriteV(ConsoleColors color, const wxChar *fmt, va_list list) const;
virtual void DoWrite( const wxChar* msg ) const
{
Console.DoWriteLn( msg );
}
virtual void DoWrite(const wxChar *msg) const
{
Console.DoWriteLn(msg);
}
};

View File

@ -18,43 +18,43 @@
// This header contains non-optimized implementation of memzero_ptr and memset8, etc
template< u32 data, typename T >
static __fi void memset32( T& obj )
template <u32 data, typename T>
static __fi void memset32(T &obj)
{
// this function works on 32-bit aligned lengths of data only.
// If the data length is not a factor of 32 bits, the C++ optimizing compiler will
// probably just generate mysteriously broken code in Release builds. ;)
// this function works on 32-bit aligned lengths of data only.
// If the data length is not a factor of 32 bits, the C++ optimizing compiler will
// probably just generate mysteriously broken code in Release builds. ;)
pxAssume((sizeof(T) & 0x3) == 0);
pxAssume((sizeof(T) & 0x3) == 0);
u32* dest = (u32*)&obj;
for( int i=sizeof(T)>>2; i; --i, ++dest )
*dest = data;
u32 *dest = (u32 *)&obj;
for (int i = sizeof(T) >> 2; i; --i, ++dest)
*dest = data;
}
template< typename T >
static __fi void memzero( T& obj )
template <typename T>
static __fi void memzero(T &obj)
{
memset( &obj, 0, sizeof( T ) );
memset(&obj, 0, sizeof(T));
}
template< u8 data, typename T >
static __fi void memset8( T& obj )
template <u8 data, typename T>
static __fi void memset8(T &obj)
{
// Aligned sizes use the optimized 32 bit inline memset. Unaligned sizes use memset.
if( (sizeof(T) & 0x3) != 0 )
memset( &obj, data, sizeof( T ) );
else {
const u32 data32 = data + (data<<8) + (data<<16) + (data<<24);
memset32<data32>( obj );
}
// Aligned sizes use the optimized 32 bit inline memset. Unaligned sizes use memset.
if ((sizeof(T) & 0x3) != 0)
memset(&obj, data, sizeof(T));
else {
const u32 data32 = data + (data << 8) + (data << 16) + (data << 24);
memset32<data32>(obj);
}
}
// Code is only called in the init so no need to bother with ASM
template< u8 data, size_t bytes >
static __fi void memset_8( void *dest )
template <u8 data, size_t bytes>
static __fi void memset_8(void *dest)
{
memset(dest, data, bytes);
memset(dest, data, bytes);
}
#endif

View File

@ -29,50 +29,74 @@
class pxCheckBox : public wxPanelWithHelpers
{
protected:
wxCheckBox* m_checkbox;
pxStaticText* m_subtext;
wxCheckBox *m_checkbox;
pxStaticText *m_subtext;
// padding below the subtext (if there's subtext). If there's no subtext, this value is unused.
int m_subPadding;
// padding below the subtext (if there's subtext). If there's no subtext, this value is unused.
int m_subPadding;
wxSizerItem *m_sizerItem_subtext;
wxSizerItem* m_sizerItem_subtext;
public:
pxCheckBox( wxWindow* parent, const wxString& label, const wxString& subtext=wxEmptyString, int flags = wxCHK_2STATE );
pxCheckBox( wxWindow* parent, const wxString& label, int flags );
virtual ~pxCheckBox() throw() {}
pxCheckBox(wxWindow *parent, const wxString &label, const wxString &subtext = wxEmptyString, int flags = wxCHK_2STATE);
pxCheckBox(wxWindow *parent, const wxString &label, int flags);
virtual ~pxCheckBox() throw() {}
bool HasSubText() const { return m_subtext != NULL; }
const pxStaticText* GetSubText() const { return m_subtext; }
bool HasSubText() const { return m_subtext != NULL; }
const pxStaticText *GetSubText() const { return m_subtext; }
pxCheckBox& SetSubPadding( int pad );
pxCheckBox& SetToolTip( const wxString& tip );
pxCheckBox& SetValue( bool val );
pxCheckBox& SetIndeterminate();
pxCheckBox& SetState( wxCheckBoxState state );
pxCheckBox &SetSubPadding(int pad);
pxCheckBox &SetToolTip(const wxString &tip);
pxCheckBox &SetValue(bool val);
pxCheckBox &SetIndeterminate();
pxCheckBox &SetState(wxCheckBoxState state);
wxCheckBoxState GetState() const { pxAssert( m_checkbox != NULL ); return m_checkbox->Get3StateValue(); }
bool GetValue() const { pxAssert( m_checkbox != NULL ); return m_checkbox->GetValue(); }
bool IsChecked() const { pxAssert( m_checkbox != NULL ); return m_checkbox->IsChecked(); }
bool IsIndeterminate() const { pxAssert( m_checkbox != NULL ); return m_checkbox->Get3StateValue() == wxCHK_UNDETERMINED; }
operator wxCheckBox&() { pxAssert( m_checkbox != NULL ); return *m_checkbox; }
operator const wxCheckBox&() const { pxAssert( m_checkbox != NULL ); return *m_checkbox; }
wxCheckBoxState GetState() const
{
pxAssert(m_checkbox != NULL);
return m_checkbox->Get3StateValue();
}
bool GetValue() const
{
pxAssert(m_checkbox != NULL);
return m_checkbox->GetValue();
}
bool IsChecked() const
{
pxAssert(m_checkbox != NULL);
return m_checkbox->IsChecked();
}
bool IsIndeterminate() const
{
pxAssert(m_checkbox != NULL);
return m_checkbox->Get3StateValue() == wxCHK_UNDETERMINED;
}
operator wxCheckBox &()
{
pxAssert(m_checkbox != NULL);
return *m_checkbox;
}
operator const wxCheckBox &() const
{
pxAssert(m_checkbox != NULL);
return *m_checkbox;
}
wxCheckBox* GetWxPtr() { return m_checkbox; }
const wxCheckBox* GetWxPtr() const { return m_checkbox; }
wxCheckBox *GetWxPtr() { return m_checkbox; }
const wxCheckBox *GetWxPtr() const { return m_checkbox; }
//wxWindowID GetId() const { pxAssert( m_checkbox != NULL ); return m_checkbox->GetId(); }
//wxWindowID GetId() const { pxAssert( m_checkbox != NULL ); return m_checkbox->GetId(); }
protected:
void Init( const wxString& label, const wxString& subtext, int flags );
void OnCheckpartCommand( wxCommandEvent& evt );
void OnSubtextClicked( wxCommandEvent& evt );
void Init(const wxString &label, const wxString &subtext, int flags);
void OnCheckpartCommand(wxCommandEvent &evt);
void OnSubtextClicked(wxCommandEvent &evt);
};
extern void operator+=( wxSizer& target, pxCheckBox& src );
extern void operator+=(wxSizer &target, pxCheckBox &src);
template<>
inline void operator+=( wxSizer& target, const pxWindowAndFlags<pxCheckBox>& src )
template <>
inline void operator+=(wxSizer &target, const pxWindowAndFlags<pxCheckBox> &src)
{
target.Add( src.window, src.flags );
target.Add(src.window, src.flags);
}

View File

@ -26,36 +26,36 @@ typedef void FnType_Void();
// --------------------------------------------------------------------------------------
class SynchronousActionState
{
DeclareNoncopyableObject( SynchronousActionState );
DeclareNoncopyableObject(SynchronousActionState);
protected:
bool m_posted;
Threading::Semaphore m_sema;
ScopedExcept m_exception;
bool m_posted;
Threading::Semaphore m_sema;
ScopedExcept m_exception;
public:
sptr return_value;
sptr return_value;
SynchronousActionState()
{
m_posted = false;
return_value = 0;
}
SynchronousActionState()
{
m_posted = false;
return_value = 0;
}
virtual ~SynchronousActionState() throw() {}
virtual ~SynchronousActionState() throw() {}
void SetException( const BaseException& ex );
void SetException( BaseException* ex );
void SetException(const BaseException &ex);
void SetException(BaseException *ex);
Threading::Semaphore& GetSemaphore() { return m_sema; }
const Threading::Semaphore& GetSemaphore() const { return m_sema; }
Threading::Semaphore &GetSemaphore() { return m_sema; }
const Threading::Semaphore &GetSemaphore() const { return m_sema; }
void RethrowException() const;
int WaitForResult();
int WaitForResult_NoExceptions();
void PostResult( int res );
void ClearResult();
void PostResult();
void RethrowException() const;
int WaitForResult();
int WaitForResult_NoExceptions();
void PostResult(int res);
void ClearResult();
void PostResult();
};
@ -68,18 +68,20 @@ public:
//
class pxSimpleEvent : public wxEvent
{
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSimpleEvent)
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSimpleEvent)
public:
explicit pxSimpleEvent( int evtid=0 )
: wxEvent(0, evtid)
{ }
explicit pxSimpleEvent(int evtid = 0)
: wxEvent(0, evtid)
{
}
pxSimpleEvent( wxWindowID winId, int evtid )
: wxEvent(winId, evtid)
{ }
pxSimpleEvent(wxWindowID winId, int evtid)
: wxEvent(winId, evtid)
{
}
virtual wxEvent *Clone() const { return new pxSimpleEvent(*this); }
virtual wxEvent *Clone() const { return new pxSimpleEvent(*this); }
};
// --------------------------------------------------------------------------------------
@ -91,41 +93,41 @@ wxDECLARE_EVENT(pxEvt_InvokeAction, pxActionEvent);
class pxActionEvent : public wxEvent
{
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxActionEvent)
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxActionEvent)
protected:
SynchronousActionState* m_state;
SynchronousActionState *m_state;
public:
virtual ~pxActionEvent() throw() { }
virtual pxActionEvent *Clone() const { return new pxActionEvent(*this); }
virtual ~pxActionEvent() throw() {}
virtual pxActionEvent *Clone() const { return new pxActionEvent(*this); }
explicit pxActionEvent( SynchronousActionState* sema=NULL, int msgtype=pxEvt_InvokeAction );
explicit pxActionEvent( SynchronousActionState& sema, int msgtype=pxEvt_InvokeAction );
pxActionEvent( const pxActionEvent& src );
explicit pxActionEvent(SynchronousActionState *sema = NULL, int msgtype = pxEvt_InvokeAction);
explicit pxActionEvent(SynchronousActionState &sema, int msgtype = pxEvt_InvokeAction);
pxActionEvent(const pxActionEvent &src);
Threading::Semaphore* GetSemaphore() const { return m_state ? &m_state->GetSemaphore() : NULL; }
Threading::Semaphore *GetSemaphore() const { return m_state ? &m_state->GetSemaphore() : NULL; }
const SynchronousActionState* GetSyncState() const { return m_state; }
SynchronousActionState* GetSyncState() { return m_state; }
const SynchronousActionState *GetSyncState() const { return m_state; }
SynchronousActionState *GetSyncState() { return m_state; }
void SetSyncState( SynchronousActionState* obj ) { m_state = obj; }
void SetSyncState( SynchronousActionState& obj ) { m_state = &obj; }
void SetSyncState(SynchronousActionState *obj) { m_state = obj; }
void SetSyncState(SynchronousActionState &obj) { m_state = &obj; }
virtual void SetException( BaseException* ex );
void SetException( const BaseException& ex );
virtual void SetException(BaseException *ex);
void SetException(const BaseException &ex);
virtual void _DoInvokeEvent();
virtual void _DoInvokeEvent();
protected:
// Extending classes should implement this method to perfoem whatever action it is
// the event is supposed to do. :) Thread affinity is garaunteed to be the Main/UI
// thread, and exceptions will be handled automatically.
//
// Exception note: exceptions are passed back to the thread that posted the event
// to the queue, when possible. If the calling thread is not blocking for a result
// from this event, then the exception will be posted to the Main/UI thread instead.
virtual void InvokeEvent() {}
// Extending classes should implement this method to perfoem whatever action it is
// the event is supposed to do. :) Thread affinity is garaunteed to be the Main/UI
// thread, and exceptions will be handled automatically.
//
// Exception note: exceptions are passed back to the thread that posted the event
// to the queue, when possible. If the calling thread is not blocking for a result
// from this event, then the exception will be posted to the Main/UI thread instead.
virtual void InvokeEvent() {}
};
@ -134,27 +136,27 @@ protected:
// --------------------------------------------------------------------------------------
class pxExceptionEvent : public pxActionEvent
{
typedef pxActionEvent _parent;
typedef pxActionEvent _parent;
protected:
BaseException* m_except;
BaseException *m_except;
public:
pxExceptionEvent( BaseException* ex=NULL )
{
m_except = ex;
}
pxExceptionEvent(BaseException *ex = NULL)
{
m_except = ex;
}
pxExceptionEvent( const BaseException& ex );
pxExceptionEvent(const BaseException &ex);
virtual ~pxExceptionEvent() throw()
{
}
virtual ~pxExceptionEvent() throw()
{
}
virtual pxExceptionEvent *Clone() const { return new pxExceptionEvent(*this); }
virtual pxExceptionEvent *Clone() const { return new pxExceptionEvent(*this); }
protected:
void InvokeEvent();
void InvokeEvent();
};
// --------------------------------------------------------------------------------------
@ -163,29 +165,29 @@ protected:
class pxSynchronousCommandEvent : public wxCommandEvent
{
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSynchronousCommandEvent)
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSynchronousCommandEvent)
protected:
SynchronousActionState* m_sync;
wxEventType m_realEvent;
SynchronousActionState *m_sync;
wxEventType m_realEvent;
public:
virtual ~pxSynchronousCommandEvent() throw() { }
virtual pxSynchronousCommandEvent *Clone() const { return new pxSynchronousCommandEvent(*this); }
virtual ~pxSynchronousCommandEvent() throw() {}
virtual pxSynchronousCommandEvent *Clone() const { return new pxSynchronousCommandEvent(*this); }
pxSynchronousCommandEvent(SynchronousActionState* sema=NULL, wxEventType commandType = wxEVT_NULL, int winid = 0);
pxSynchronousCommandEvent(SynchronousActionState& sema, wxEventType commandType = wxEVT_NULL, int winid = 0);
pxSynchronousCommandEvent(SynchronousActionState *sema = NULL, wxEventType commandType = wxEVT_NULL, int winid = 0);
pxSynchronousCommandEvent(SynchronousActionState &sema, wxEventType commandType = wxEVT_NULL, int winid = 0);
pxSynchronousCommandEvent(SynchronousActionState* sema, const wxCommandEvent& evt);
pxSynchronousCommandEvent(SynchronousActionState& sema, const wxCommandEvent& evt);
pxSynchronousCommandEvent(SynchronousActionState *sema, const wxCommandEvent &evt);
pxSynchronousCommandEvent(SynchronousActionState &sema, const wxCommandEvent &evt);
pxSynchronousCommandEvent(const pxSynchronousCommandEvent& src);
pxSynchronousCommandEvent(const pxSynchronousCommandEvent &src);
Threading::Semaphore* GetSemaphore() { return m_sync ? &m_sync->GetSemaphore() : NULL; }
wxEventType GetRealEventType() const { return m_realEvent; }
Threading::Semaphore *GetSemaphore() { return m_sync ? &m_sync->GetSemaphore() : NULL; }
wxEventType GetRealEventType() const { return m_realEvent; }
void SetException( BaseException* ex );
void SetException( const BaseException& ex );
void SetException(BaseException *ex);
void SetException(const BaseException &ex);
};
wxDECLARE_EVENT(pxEvt_SynchronousCommand, pxSynchronousCommandEvent);
@ -195,23 +197,23 @@ wxDECLARE_EVENT(pxEvt_SynchronousCommand, pxSynchronousCommandEvent);
// --------------------------------------------------------------------------------------
class BaseMessageBoxEvent : public pxActionEvent
{
typedef pxActionEvent _parent;
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(BaseMessageBoxEvent)
typedef pxActionEvent _parent;
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(BaseMessageBoxEvent)
protected:
wxString m_Content;
wxString m_Content;
public:
virtual ~BaseMessageBoxEvent() throw() { }
virtual BaseMessageBoxEvent *Clone() const { return new BaseMessageBoxEvent(*this); }
virtual ~BaseMessageBoxEvent() throw() {}
virtual BaseMessageBoxEvent *Clone() const { return new BaseMessageBoxEvent(*this); }
explicit BaseMessageBoxEvent( const wxString& content=wxEmptyString, SynchronousActionState* instdata=NULL );
BaseMessageBoxEvent( const wxString& content, SynchronousActionState& instdata );
BaseMessageBoxEvent( const BaseMessageBoxEvent& event );
explicit BaseMessageBoxEvent(const wxString &content = wxEmptyString, SynchronousActionState *instdata = NULL);
BaseMessageBoxEvent(const wxString &content, SynchronousActionState &instdata);
BaseMessageBoxEvent(const BaseMessageBoxEvent &event);
protected:
virtual void InvokeEvent();
virtual int _DoDialog() const;
virtual void InvokeEvent();
virtual int _DoDialog() const;
};
// --------------------------------------------------------------------------------------
@ -220,82 +222,134 @@ protected:
class MsgButtons
{
protected:
BITFIELD32()
bool
m_OK :1,
m_Cancel :1,
m_Yes :1,
m_No :1,
m_AllowToAll:1,
m_Apply :1,
m_Abort :1,
m_Retry :1,
m_Ignore :1,
m_Reset :1,
m_Close :1;
BITFIELD_END
BITFIELD32()
bool
m_OK : 1,
m_Cancel : 1,
m_Yes : 1,
m_No : 1,
m_AllowToAll : 1,
m_Apply : 1,
m_Abort : 1,
m_Retry : 1,
m_Ignore : 1,
m_Reset : 1,
m_Close : 1;
BITFIELD_END
wxString m_CustomLabel;
wxString m_CustomLabelId;
wxString m_CustomLabel;
wxString m_CustomLabelId;
public:
MsgButtons() { bitset = 0; }
MsgButtons() { bitset = 0; }
MsgButtons& OK() { m_OK = true; return *this; }
MsgButtons& Cancel() { m_Cancel = true; return *this; }
MsgButtons& Apply() { m_Apply = true; return *this; }
MsgButtons& Yes() { m_Yes = true; return *this; }
MsgButtons& No() { m_No = true; return *this; }
MsgButtons& ToAll() { m_AllowToAll = true; return *this; }
MsgButtons &OK()
{
m_OK = true;
return *this;
}
MsgButtons &Cancel()
{
m_Cancel = true;
return *this;
}
MsgButtons &Apply()
{
m_Apply = true;
return *this;
}
MsgButtons &Yes()
{
m_Yes = true;
return *this;
}
MsgButtons &No()
{
m_No = true;
return *this;
}
MsgButtons &ToAll()
{
m_AllowToAll = true;
return *this;
}
MsgButtons& Abort() { m_Abort = true; return *this; }
MsgButtons& Retry() { m_Retry = true; return *this; }
MsgButtons& Ignore() { m_Ignore = true; return *this; }
MsgButtons& Reset() { m_Reset = true; return *this; }
MsgButtons& Close() { m_Close = true; return *this; }
MsgButtons &Abort()
{
m_Abort = true;
return *this;
}
MsgButtons &Retry()
{
m_Retry = true;
return *this;
}
MsgButtons &Ignore()
{
m_Ignore = true;
return *this;
}
MsgButtons &Reset()
{
m_Reset = true;
return *this;
}
MsgButtons &Close()
{
m_Close = true;
return *this;
}
// label - native language label displayed to user
// id - raw ASCII identifier used in the config file (do not translate, hence char*)
MsgButtons& Custom( const wxString& label, const char* id )
{
m_CustomLabel = label;
m_CustomLabelId = fromUTF8(id);
return *this;
}
// label - native language label displayed to user
// id - raw ASCII identifier used in the config file (do not translate, hence char*)
MsgButtons &Custom(const wxString &label, const char *id)
{
m_CustomLabel = label;
m_CustomLabelId = fromUTF8(id);
return *this;
}
MsgButtons& OKCancel() { m_OK = m_Cancel = true; return *this; }
MsgButtons& YesNo() { m_Yes = m_No = true; return *this; }
MsgButtons &OKCancel()
{
m_OK = m_Cancel = true;
return *this;
}
MsgButtons &YesNo()
{
m_Yes = m_No = true;
return *this;
}
bool HasOK() const { return m_OK; }
bool HasCancel() const { return m_Cancel; }
bool HasApply() const { return m_Apply; }
bool HasYes() const { return m_Yes; }
bool HasNo() const { return m_No; }
bool AllowsToAll() const{ return m_AllowToAll; }
bool HasOK() const { return m_OK; }
bool HasCancel() const { return m_Cancel; }
bool HasApply() const { return m_Apply; }
bool HasYes() const { return m_Yes; }
bool HasNo() const { return m_No; }
bool AllowsToAll() const { return m_AllowToAll; }
bool HasAbort() const { return m_Abort; }
bool HasRetry() const { return m_Retry; }
bool HasIgnore() const { return m_Ignore; }
bool HasReset() const { return m_Reset; }
bool HasClose() const { return m_Close; }
bool HasAbort() const { return m_Abort; }
bool HasRetry() const { return m_Retry; }
bool HasIgnore() const { return m_Ignore; }
bool HasReset() const { return m_Reset; }
bool HasClose() const { return m_Close; }
bool HasCustom() const { return !m_CustomLabel.IsEmpty(); }
const wxString& GetCustomLabel() const { return m_CustomLabel; }
const wxString& GetCustomLabelId() const { return m_CustomLabelId; }
bool HasCustom() const { return !m_CustomLabel.IsEmpty(); }
const wxString &GetCustomLabel() const { return m_CustomLabel; }
const wxString &GetCustomLabelId() const { return m_CustomLabelId; }
bool Allows( wxWindowID id ) const;
void SetBestFocus( wxWindow* dialog ) const;
void SetBestFocus( wxWindow& dialog ) const;
bool Allows(wxWindowID id) const;
void SetBestFocus(wxWindow *dialog) const;
void SetBestFocus(wxWindow &dialog) const;
bool operator ==( const MsgButtons& right ) const
{
return OpEqu( bitset );
}
bool operator==(const MsgButtons &right) const
{
return OpEqu(bitset);
}
bool operator !=( const MsgButtons& right ) const
{
return !OpEqu( bitset );
}
bool operator!=(const MsgButtons &right) const
{
return !OpEqu(bitset);
}
};
// --------------------------------------------------------------------------------------
@ -318,24 +372,24 @@ public:
//
class pxMessageBoxEvent : public BaseMessageBoxEvent
{
typedef BaseMessageBoxEvent _parent;
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxMessageBoxEvent)
typedef BaseMessageBoxEvent _parent;
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxMessageBoxEvent)
protected:
wxString m_Title;
MsgButtons m_Buttons;
wxString m_Title;
MsgButtons m_Buttons;
public:
virtual ~pxMessageBoxEvent() throw() { }
virtual pxMessageBoxEvent *Clone() const { return new pxMessageBoxEvent(*this); }
virtual ~pxMessageBoxEvent() throw() {}
virtual pxMessageBoxEvent *Clone() const { return new pxMessageBoxEvent(*this); }
pxMessageBoxEvent() {}
pxMessageBoxEvent( const wxString& title, const wxString& content, const MsgButtons& buttons, SynchronousActionState& instdata );
pxMessageBoxEvent( const wxString& title, const wxString& content, const MsgButtons& buttons, SynchronousActionState* instdata=NULL );
pxMessageBoxEvent( const pxMessageBoxEvent& event );
pxMessageBoxEvent() {}
pxMessageBoxEvent(const wxString &title, const wxString &content, const MsgButtons &buttons, SynchronousActionState &instdata);
pxMessageBoxEvent(const wxString &title, const wxString &content, const MsgButtons &buttons, SynchronousActionState *instdata = NULL);
pxMessageBoxEvent(const pxMessageBoxEvent &event);
protected:
int _DoDialog() const;
int _DoDialog() const;
};
// --------------------------------------------------------------------------------------
@ -343,22 +397,22 @@ protected:
// --------------------------------------------------------------------------------------
class pxAssertionEvent : public BaseMessageBoxEvent
{
typedef BaseMessageBoxEvent _parent;
DECLARE_DYNAMIC_CLASS_NO_ASSIGN( pxAssertionEvent )
typedef BaseMessageBoxEvent _parent;
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxAssertionEvent)
protected:
wxString m_Stacktrace;
wxString m_Stacktrace;
public:
virtual ~pxAssertionEvent() throw() { }
virtual pxAssertionEvent *Clone() const { return new pxAssertionEvent(*this); }
virtual ~pxAssertionEvent() throw() {}
virtual pxAssertionEvent *Clone() const { return new pxAssertionEvent(*this); }
pxAssertionEvent( const wxString& content=wxEmptyString, const wxString& trace=wxEmptyString, SynchronousActionState* instdata=NULL );
pxAssertionEvent( const wxString& content, const wxString& trace, SynchronousActionState& instdata );
pxAssertionEvent( const pxAssertionEvent& event );
pxAssertionEvent(const wxString &content = wxEmptyString, const wxString &trace = wxEmptyString, SynchronousActionState *instdata = NULL);
pxAssertionEvent(const wxString &content, const wxString &trace, SynchronousActionState &instdata);
pxAssertionEvent(const pxAssertionEvent &event);
pxAssertionEvent& SetStacktrace( const wxString& trace );
pxAssertionEvent &SetStacktrace(const wxString &trace);
protected:
int _DoDialog() const;
int _DoDialog() const;
};

View File

@ -40,12 +40,12 @@ extern const wxPoint wxDefaultPosition;
namespace Threading
{
class Mutex;
class Semaphore;
class pxThread;
class Mutex;
class Semaphore;
class pxThread;
}
namespace Exception
{
class BaseException;
class BaseException;
}

View File

@ -25,45 +25,45 @@
struct RadioPanelItem
{
wxString Label;
wxString SubText;
wxString ToolTip;
wxString Label;
wxString SubText;
wxString ToolTip;
int SomeInt;
void* SomePtr;
int SomeInt;
void *SomePtr;
RadioPanelItem( const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString )
: Label( label )
, SubText( subtext )
, ToolTip( tooltip )
{
SomeInt = 0;
SomePtr = NULL;
}
RadioPanelItem(const wxString &label, const wxString &subtext = wxEmptyString, const wxString &tooltip = wxEmptyString)
: Label(label)
, SubText(subtext)
, ToolTip(tooltip)
{
SomeInt = 0;
SomePtr = NULL;
}
RadioPanelItem& SetToolTip( const wxString& tip )
{
ToolTip = tip;
return *this;
}
RadioPanelItem &SetToolTip(const wxString &tip)
{
ToolTip = tip;
return *this;
}
RadioPanelItem& SetSubText( const wxString& text )
{
SubText = text;
return *this;
}
RadioPanelItem& SetInt( int intval )
{
SomeInt = intval;
return *this;
}
RadioPanelItem &SetSubText(const wxString &text)
{
SubText = text;
return *this;
}
RadioPanelItem& SetPtr( void* ptrval )
{
SomePtr = ptrval;
return *this;
}
RadioPanelItem &SetInt(int intval)
{
SomeInt = intval;
return *this;
}
RadioPanelItem &SetPtr(void *ptrval)
{
SomePtr = ptrval;
return *this;
}
};
@ -71,8 +71,8 @@ struct RadioPanelItem
// wrapped and re-wrapped with multiple calls to OnResize().
struct RadioPanelObjects
{
wxRadioButton* LabelObj;
pxStaticText* SubTextObj;
wxRadioButton *LabelObj;
pxStaticText *SubTextObj;
};
// --------------------------------------------------------------------------------------
@ -91,86 +91,86 @@ struct RadioPanelObjects
class pxRadioPanel : public wxPanelWithHelpers
{
protected:
typedef std::vector<RadioPanelItem> ButtonArray;
typedef SafeArray<RadioPanelObjects> ButtonObjArray;
typedef std::vector<RadioPanelItem> ButtonArray;
typedef SafeArray<RadioPanelObjects> ButtonObjArray;
ButtonArray m_buttonStrings;
ButtonObjArray m_objects;
ButtonArray m_buttonStrings;
ButtonObjArray m_objects;
bool m_IsRealized;
bool m_IsRealized;
wxSize m_padding;
int m_Indentation;
int m_DefaultIdx; // index of the default option (gets specific color/font treatment)
wxSize m_padding;
int m_Indentation;
int m_DefaultIdx; // index of the default option (gets specific color/font treatment)
public:
template< int size >
pxRadioPanel( wxWindow* parent, const RadioPanelItem (&src)[size] )
: wxPanelWithHelpers( parent, wxVERTICAL )
{
Init( src, size );
}
template <int size>
pxRadioPanel(wxWindow *parent, const RadioPanelItem (&src)[size])
: wxPanelWithHelpers(parent, wxVERTICAL)
{
Init(src, size);
}
pxRadioPanel( wxWindow* parent )
: wxPanelWithHelpers( parent, wxVERTICAL )
{
Init();
}
pxRadioPanel(wxWindow *parent)
: wxPanelWithHelpers(parent, wxVERTICAL)
{
Init();
}
virtual ~pxRadioPanel() throw() {}
virtual ~pxRadioPanel() throw() {}
void Reset();
void Realize();
void Reset();
void Realize();
pxStaticText* GetSubText( int idx );
const pxStaticText* GetSubText( int idx ) const;
pxRadioPanel& Append( const RadioPanelItem& entry );
pxStaticText *GetSubText(int idx);
const pxStaticText *GetSubText(int idx) const;
pxRadioPanel &Append(const RadioPanelItem &entry);
pxRadioPanel& SetToolTip( int idx, const wxString& tip );
pxRadioPanel& SetSelection( int idx );
pxRadioPanel& SetDefaultItem( int idx );
pxRadioPanel& EnableItem( int idx, bool enable=true );
pxRadioPanel &SetToolTip(int idx, const wxString &tip);
pxRadioPanel &SetSelection(int idx);
pxRadioPanel &SetDefaultItem(int idx);
pxRadioPanel &EnableItem(int idx, bool enable = true);
const RadioPanelItem& Item(int idx) const;
RadioPanelItem& Item(int idx);
const RadioPanelItem &Item(int idx) const;
RadioPanelItem &Item(int idx);
int GetSelection() const;
wxWindowID GetSelectionId() const;
bool IsSelected( int idx ) const;
int GetSelection() const;
wxWindowID GetSelectionId() const;
bool IsSelected(int idx) const;
const RadioPanelItem& SelectedItem() const { return Item(GetSelection()); }
RadioPanelItem& SelectedItem() { return Item(GetSelection()); }
const RadioPanelItem &SelectedItem() const { return Item(GetSelection()); }
RadioPanelItem &SelectedItem() { return Item(GetSelection()); }
wxRadioButton* GetButton( int idx );
const wxRadioButton* GetButton( int idx ) const;
wxRadioButton *GetButton(int idx);
const wxRadioButton *GetButton(int idx) const;
int GetPaddingVert() const { return m_padding.GetHeight(); }
int GetIndentation() const { return m_Indentation; }
int GetPaddingVert() const { return m_padding.GetHeight(); }
int GetIndentation() const { return m_Indentation; }
pxRadioPanel& SetPaddingHoriz( int newpad )
{
m_padding.SetHeight( newpad );
return *this;
}
pxRadioPanel &SetPaddingHoriz(int newpad)
{
m_padding.SetHeight(newpad);
return *this;
}
pxRadioPanel& SetIndentation( int newdent )
{
m_Indentation = newdent;
return *this;
}
pxRadioPanel &SetIndentation(int newdent)
{
m_Indentation = newdent;
return *this;
}
bool HasSubText( int idx ) const
{
return !m_buttonStrings[idx].SubText.IsEmpty();
}
bool HasSubText(int idx) const
{
return !m_buttonStrings[idx].SubText.IsEmpty();
}
pxRadioPanel& Append( const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString )
{
return Append( RadioPanelItem(label, subtext, tooltip) );
}
pxRadioPanel &Append(const wxString &label, const wxString &subtext = wxEmptyString, const wxString &tooltip = wxEmptyString)
{
return Append(RadioPanelItem(label, subtext, tooltip));
}
protected:
void Init( const RadioPanelItem* srcArray=NULL, int arrsize=0 );
void _setToolTipImmediate( int idx, const wxString &tip );
void _RealizeDefaultOption();
void Init(const RadioPanelItem *srcArray = NULL, int arrsize = 0);
void _setToolTipImmediate(int idx, const wxString &tip);
void _RealizeDefaultOption();
};

View File

@ -33,93 +33,92 @@
//
class pxStaticText : public wxControl
{
typedef wxControl _parent;
typedef wxControl _parent;
protected:
wxString m_label;
wxString m_wrappedLabel;
wxString m_label;
wxString m_wrappedLabel;
wxAlignment m_align;
bool m_autowrap;
int m_wrappedWidth;
int m_heightInLines;
wxAlignment m_align;
bool m_autowrap;
int m_wrappedWidth;
int m_heightInLines;
int m_paddingPix_horiz;
int m_paddingPix_vert;
float m_paddingPct_horiz;
float m_paddingPct_vert;
int m_paddingPix_horiz;
int m_paddingPix_vert;
float m_paddingPct_horiz;
float m_paddingPct_vert;
protected:
explicit pxStaticText( wxWindow* parent=NULL );
explicit pxStaticText(wxWindow *parent = NULL);
// wxWindow overloads!
bool AcceptsFocus() const { return false; }
bool HasTransparentBackground() { return true; }
void DoSetSize(int x, int y, int w, int h, int sizeFlags = wxSIZE_AUTO);
// wxWindow overloads!
bool AcceptsFocus() const { return false; }
bool HasTransparentBackground() { return true; }
void DoSetSize(int x, int y, int w, int h, int sizeFlags = wxSIZE_AUTO);
public:
pxStaticText( wxWindow* parent, const wxString& label, wxAlignment align=wxALIGN_CENTRE_HORIZONTAL );
pxStaticText( wxWindow* parent, int heightInLines, const wxString& label, wxAlignment align=wxALIGN_CENTRE_HORIZONTAL );
virtual ~pxStaticText() throw() {}
pxStaticText(wxWindow *parent, const wxString &label, wxAlignment align = wxALIGN_CENTRE_HORIZONTAL);
pxStaticText(wxWindow *parent, int heightInLines, const wxString &label, wxAlignment align = wxALIGN_CENTRE_HORIZONTAL);
virtual ~pxStaticText() throw() {}
wxFont GetFontOk() const;
bool Enable( bool enabled=true );
wxFont GetFontOk() const;
bool Enable(bool enabled = true);
virtual void SetLabel(const wxString& label);
virtual wxString GetLabel() const { return m_label; }
virtual void SetLabel(const wxString &label);
virtual wxString GetLabel() const { return m_label; }
pxStaticText& SetMinWidth( int width );
pxStaticText& SetMinHeight( int height );
pxStaticText &SetMinWidth(int width);
pxStaticText &SetMinHeight(int height);
pxStaticText& SetHeight( int lines );
pxStaticText& Align( wxAlignment align );
pxStaticText& Bold();
pxStaticText& WrapAt( int width );
pxStaticText &SetHeight(int lines);
pxStaticText &Align(wxAlignment align);
pxStaticText &Bold();
pxStaticText &WrapAt(int width);
pxStaticText& Unwrapped();
pxStaticText &Unwrapped();
pxStaticText& PaddingPixH( int pixels );
pxStaticText& PaddingPixV( int pixels );
pxStaticText &PaddingPixH(int pixels);
pxStaticText &PaddingPixV(int pixels);
pxStaticText& PaddingPctH( float pct );
pxStaticText& PaddingPctV( float pct );
//pxStaticText& DoBestGuessHeight();
pxStaticText &PaddingPctH(float pct);
pxStaticText &PaddingPctV(float pct);
//pxStaticText& DoBestGuessHeight();
protected:
void SetPaddingDefaults();
void Init( const wxString& label );
void SetPaddingDefaults();
void Init(const wxString &label);
wxSize GetBestWrappedSize( const wxClientDC& dc ) const;
wxSize DoGetBestSize() const;
wxSize GetBestWrappedSize(const wxClientDC &dc) const;
wxSize DoGetBestSize() const;
int calcPaddingWidth( int newWidth ) const;
int calcPaddingHeight( int newHeight ) const;
int calcPaddingWidth(int newWidth) const;
int calcPaddingHeight(int newHeight) const;
void paintEvent(wxPaintEvent& evt);
void paintEvent(wxPaintEvent &evt);
void UpdateWrapping( bool textChanged );
bool _updateWrapping( bool textChanged );
void UpdateWrapping(bool textChanged);
bool _updateWrapping(bool textChanged);
};
class pxStaticHeading : public pxStaticText
{
typedef pxStaticText _parent;
typedef pxStaticText _parent;
public:
pxStaticHeading( wxWindow* parent=NULL, const wxString& label=wxEmptyString );
pxStaticHeading( wxWindow* parent, int heightInLines, const wxString& label=wxEmptyString );
virtual ~pxStaticHeading() throw() {}
pxStaticHeading(wxWindow *parent = NULL, const wxString &label = wxEmptyString);
pxStaticHeading(wxWindow *parent, int heightInLines, const wxString &label = wxEmptyString);
virtual ~pxStaticHeading() throw() {}
protected:
void SetPaddingDefaults();
void SetPaddingDefaults();
};
extern void operator+=( wxSizer& target, pxStaticText& src );
extern void operator+=(wxSizer &target, pxStaticText &src);
template<>
inline void operator+=( wxSizer& target, const pxWindowAndFlags<pxStaticText>& src )
template <>
inline void operator+=(wxSizer &target, const pxWindowAndFlags<pxStaticText> &src)
{
target.Add( src.window, src.flags );
target.Add(src.window, src.flags);
}

View File

@ -23,28 +23,28 @@
// --------------------------------------------------------------------------------------
class pxStreamBase
{
DeclareNoncopyableObject(pxStreamBase);
DeclareNoncopyableObject(pxStreamBase);
protected:
// Filename of the stream, provided by the creator/caller. This is typically used *only*
// for generating comprehensive error messages when an error occurs (the stream name is
// passed to the exception handlers).
wxString m_filename;
// Filename of the stream, provided by the creator/caller. This is typically used *only*
// for generating comprehensive error messages when an error occurs (the stream name is
// passed to the exception handlers).
wxString m_filename;
public:
pxStreamBase(const wxString& filename);
virtual ~pxStreamBase() throw() {}
pxStreamBase(const wxString &filename);
virtual ~pxStreamBase() throw() {}
// Implementing classes should return the base wxStream object (usually either a wxInputStream
// or wxOputStream derivative).
virtual wxStreamBase* GetWxStreamBase() const=0;
virtual void Close()=0;
virtual wxFileOffset Tell() const=0;
virtual wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart )=0;
// Implementing classes should return the base wxStream object (usually either a wxInputStream
// or wxOputStream derivative).
virtual wxStreamBase *GetWxStreamBase() const = 0;
virtual void Close() = 0;
virtual wxFileOffset Tell() const = 0;
virtual wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart) = 0;
virtual wxFileOffset Length() const;
bool IsOk() const;
wxString GetStreamName() const { return m_filename; }
virtual wxFileOffset Length() const;
bool IsOk() const;
wxString GetStreamName() const { return m_filename; }
};
@ -53,33 +53,33 @@ public:
// --------------------------------------------------------------------------------------
class pxOutputStream : public pxStreamBase
{
DeclareNoncopyableObject(pxOutputStream);
DeclareNoncopyableObject(pxOutputStream);
protected:
std::unique_ptr<wxOutputStream> m_stream_out;
std::unique_ptr<wxOutputStream> m_stream_out;
public:
pxOutputStream(const wxString& filename, std::unique_ptr<wxOutputStream>& output);
pxOutputStream(const wxString& filename, wxOutputStream* output);
pxOutputStream(const wxString &filename, std::unique_ptr<wxOutputStream> &output);
pxOutputStream(const wxString &filename, wxOutputStream *output);
virtual ~pxOutputStream() throw() {}
virtual void Write( const void* data, size_t size );
void SetStream( const wxString& filename, std::unique_ptr<wxOutputStream>& stream );
void SetStream( const wxString& filename, wxOutputStream* stream );
virtual ~pxOutputStream() throw() {}
virtual void Write(const void *data, size_t size);
void Close() { m_stream_out = nullptr; }
void SetStream(const wxString &filename, std::unique_ptr<wxOutputStream> &stream);
void SetStream(const wxString &filename, wxOutputStream *stream);
virtual wxStreamBase* GetWxStreamBase() const;
void Close() { m_stream_out = nullptr; }
template< typename T >
void Write( const T& data )
{
Write( &data, sizeof(data) );
}
virtual wxStreamBase *GetWxStreamBase() const;
wxFileOffset Tell() const;
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart );
template <typename T>
void Write(const T &data)
{
Write(&data, sizeof(data));
}
wxFileOffset Tell() const;
wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart);
};
// --------------------------------------------------------------------------------------
@ -87,31 +87,31 @@ public:
// --------------------------------------------------------------------------------------
class pxInputStream : public pxStreamBase
{
DeclareNoncopyableObject(pxInputStream);
DeclareNoncopyableObject(pxInputStream);
protected:
std::unique_ptr<wxInputStream> m_stream_in;
std::unique_ptr<wxInputStream> m_stream_in;
public:
pxInputStream(const wxString& filename, std::unique_ptr<wxInputStream>& input);
pxInputStream(const wxString& filename, wxInputStream* input);
pxInputStream(const wxString &filename, std::unique_ptr<wxInputStream> &input);
pxInputStream(const wxString &filename, wxInputStream *input);
virtual ~pxInputStream() throw() {}
virtual void Read( void* dest, size_t size );
void SetStream( const wxString& filename, std::unique_ptr<wxInputStream>& stream );
void SetStream( const wxString& filename, wxInputStream* stream );
virtual ~pxInputStream() throw() {}
virtual void Read(void *dest, size_t size);
void Close() { m_stream_in = nullptr; }
void SetStream(const wxString &filename, std::unique_ptr<wxInputStream> &stream);
void SetStream(const wxString &filename, wxInputStream *stream);
virtual wxStreamBase* GetWxStreamBase() const;
void Close() { m_stream_in = nullptr; }
template< typename T >
void Read( T& dest )
{
Read( &dest, sizeof(dest) );
}
virtual wxStreamBase *GetWxStreamBase() const;
wxFileOffset Tell() const;
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart );
template <typename T>
void Read(T &dest)
{
Read(&dest, sizeof(dest));
}
wxFileOffset Tell() const;
wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart);
};

View File

@ -16,30 +16,30 @@
#pragma once
#ifdef _MSC_VER
# pragma warning(disable:4063) // case '1' is not a valid value for switch()
#pragma warning(disable : 4063) // case '1' is not a valid value for switch()
#endif
// These functions are meant for memset operations of constant length only.
// For dynamic length clears, use the C-compiler provided memset instead.
template< u8 data, size_t bytes >
static __fi void memset_8( void *dest )
template <u8 data, size_t bytes>
static __fi void memset_8(void *dest)
{
memset(dest, data, bytes);
memset(dest, data, bytes);
}
// This method can clear any object-like entity -- which is anything that is not a pointer.
// Structures, static arrays, etc. No need to include sizeof() crap, this does it automatically
// for you!
template< typename T >
static __fi void memzero( T& object )
template <typename T>
static __fi void memzero(T &object)
{
memset(&object, 0, sizeof(T));
memset(&object, 0, sizeof(T));
}
// This method clears an object with the given 8 bit value.
template< u8 data, typename T >
static __fi void memset8( T& object )
template <u8 data, typename T>
static __fi void memset8(T &object)
{
memset_8<data, sizeof(T)>( &object );
memset_8<data, sizeof(T)>(&object);
}

View File

@ -32,10 +32,10 @@ class pxSynchronousCommandEvent;
class ConsoleLogSource_App : public ConsoleLogSource
{
typedef ConsoleLogSource _parent;
typedef ConsoleLogSource _parent;
public:
ConsoleLogSource_App();
ConsoleLogSource_App();
};
extern ConsoleLogSource_App pxConLog_App;
@ -49,96 +49,97 @@ extern ConsoleLogSource_App pxConLog_App;
class ModalButtonPanel : public wxPanelWithHelpers
{
public:
ModalButtonPanel( wxWindow* window, const MsgButtons& buttons );
virtual ~ModalButtonPanel() throw() { }
ModalButtonPanel(wxWindow *window, const MsgButtons &buttons);
virtual ~ModalButtonPanel() throw() {}
virtual void AddActionButton( wxWindowID id );
virtual void AddCustomButton( wxWindowID id, const wxString& label );
virtual void AddActionButton(wxWindowID id);
virtual void AddCustomButton(wxWindowID id, const wxString &label);
virtual void OnActionButtonClicked( wxCommandEvent& evt );
virtual void OnActionButtonClicked(wxCommandEvent &evt);
};
typedef std::list< wxEvent* > wxEventList;
typedef std::list<wxEvent *> wxEventList;
// --------------------------------------------------------------------------------------
// wxAppWithHelpers
// --------------------------------------------------------------------------------------
class wxAppWithHelpers : public wxApp
{
typedef wxApp _parent;
DECLARE_DYNAMIC_CLASS(wxAppWithHelpers)
typedef wxApp _parent;
DECLARE_DYNAMIC_CLASS(wxAppWithHelpers)
protected:
wxEventList m_IdleEventQueue;
Threading::MutexRecursive m_IdleEventMutex;
wxTimer m_IdleEventTimer;
wxEventList m_IdleEventQueue;
Threading::MutexRecursive m_IdleEventMutex;
wxTimer m_IdleEventTimer;
public:
wxAppWithHelpers();
virtual ~wxAppWithHelpers() {}
wxAppWithHelpers();
virtual ~wxAppWithHelpers() {}
wxAppTraits* CreateTraits();
wxAppTraits *CreateTraits();
void CleanUp();
void DeleteObject( BaseDeletableObject& obj );
void DeleteObject( BaseDeletableObject* obj )
{
if( obj == NULL ) return;
DeleteObject( *obj );
}
void CleanUp();
void DeleteThread( Threading::pxThread& obj );
void DeleteThread( Threading::pxThread* obj )
{
if( obj == NULL ) return;
DeleteThread( *obj );
}
void DeleteObject(BaseDeletableObject &obj);
void DeleteObject(BaseDeletableObject *obj)
{
if (obj == NULL)
return;
DeleteObject(*obj);
}
void PostCommand( void* clientData, int evtType, int intParam=0, long longParam=0, const wxString& stringParam=wxEmptyString );
void PostCommand( int evtType, int intParam=0, long longParam=0, const wxString& stringParam=wxEmptyString );
void PostMethod( FnType_Void* method );
void PostIdleMethod( FnType_Void* method );
void ProcessMethod( FnType_Void* method );
void DeleteThread(Threading::pxThread &obj);
void DeleteThread(Threading::pxThread *obj)
{
if (obj == NULL)
return;
DeleteThread(*obj);
}
bool Rpc_TryInvoke( FnType_Void* method );
bool Rpc_TryInvokeAsync( FnType_Void* method );
void PostCommand(void *clientData, int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString);
void PostCommand(int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString);
void PostMethod(FnType_Void *method);
void PostIdleMethod(FnType_Void *method);
void ProcessMethod(FnType_Void *method);
sptr ProcessCommand( void* clientData, int evtType, int intParam=0, long longParam=0, const wxString& stringParam=wxEmptyString );
sptr ProcessCommand( int evtType, int intParam=0, long longParam=0, const wxString& stringParam=wxEmptyString );
bool Rpc_TryInvoke(FnType_Void *method);
bool Rpc_TryInvokeAsync(FnType_Void *method);
void ProcessAction( pxActionEvent& evt );
void PostAction( const pxActionEvent& evt );
sptr ProcessCommand(void *clientData, int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString);
sptr ProcessCommand(int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString);
void Ping();
bool OnInit();
//int OnExit();
void ProcessAction(pxActionEvent &evt);
void PostAction(const pxActionEvent &evt);
void AddIdleEvent( const wxEvent& evt );
void Ping();
bool OnInit();
//int OnExit();
void PostEvent( const wxEvent& evt );
bool ProcessEvent( wxEvent& evt );
bool ProcessEvent( wxEvent* evt );
bool ProcessEvent( pxActionEvent& evt );
bool ProcessEvent( pxActionEvent* evt );
void AddIdleEvent(const wxEvent &evt);
void PostEvent(const wxEvent &evt);
bool ProcessEvent(wxEvent &evt);
bool ProcessEvent(wxEvent *evt);
bool ProcessEvent(pxActionEvent &evt);
bool ProcessEvent(pxActionEvent *evt);
protected:
void IdleEventDispatcher( const wxChar* action=wxEmptyString );
void OnIdleEvent( wxIdleEvent& evt );
void OnStartIdleEventTimer( wxCommandEvent& evt );
void OnIdleEventTimeout( wxTimerEvent& evt );
void OnDeleteObject( wxCommandEvent& evt );
void OnDeleteThread( wxCommandEvent& evt );
void OnSynchronousCommand( pxSynchronousCommandEvent& evt );
void OnInvokeAction( pxActionEvent& evt );
void IdleEventDispatcher(const wxChar *action = wxEmptyString);
void OnIdleEvent(wxIdleEvent &evt);
void OnStartIdleEventTimer(wxCommandEvent &evt);
void OnIdleEventTimeout(wxTimerEvent &evt);
void OnDeleteObject(wxCommandEvent &evt);
void OnDeleteThread(wxCommandEvent &evt);
void OnSynchronousCommand(pxSynchronousCommandEvent &evt);
void OnInvokeAction(pxActionEvent &evt);
};
namespace Msgbox
{
extern int ShowModal( BaseMessageBoxEvent& evt );
extern int ShowModal( const wxString& title, const wxString& content, const MsgButtons& buttons );
extern int ShowModal(BaseMessageBoxEvent &evt);
extern int ShowModal(const wxString &title, const wxString &content, const MsgButtons &buttons);
}

View File

@ -26,11 +26,11 @@
// which require wxCore, see wxGuiTools.h
// --------------------------------------------------------------------------------------
extern void pxExplore( const wxString& path );
extern void pxExplore( const char *path );
extern void pxExplore(const wxString &path);
extern void pxExplore(const char *path);
extern void pxLaunch( const wxString& path );
extern void pxLaunch( const char *path );
extern void pxLaunch(const wxString &path);
extern void pxLaunch(const char *path);
// --------------------------------------------------------------------------------------
// wxDoNotLogInThisScope
@ -44,29 +44,28 @@ extern void pxLaunch( const char *path );
//
class wxDoNotLogInThisScope
{
DeclareNoncopyableObject(wxDoNotLogInThisScope);
DeclareNoncopyableObject(wxDoNotLogInThisScope);
protected:
bool m_prev;
bool m_prev;
public:
wxDoNotLogInThisScope()
{
m_prev = wxLog::EnableLogging( false );
}
wxDoNotLogInThisScope()
{
m_prev = wxLog::EnableLogging(false);
}
virtual ~wxDoNotLogInThisScope() throw()
{
wxLog::EnableLogging( m_prev );
}
virtual ~wxDoNotLogInThisScope() throw()
{
wxLog::EnableLogging(m_prev);
}
};
extern wxString pxReadLine( wxInputStream& input );
extern void pxReadLine( wxInputStream& input, wxString& dest );
extern void pxReadLine( wxInputStream& input, wxString& dest, std::string& intermed );
extern bool pxReadLine( wxInputStream& input, std::string& dest );
extern void pxWriteLine( wxOutputStream& output );
extern void pxWriteLine( wxOutputStream& output, const wxString& text );
extern void pxWriteMultiline( wxOutputStream& output, const wxString& src );
extern wxString pxReadLine(wxInputStream &input);
extern void pxReadLine(wxInputStream &input, wxString &dest);
extern void pxReadLine(wxInputStream &input, wxString &dest, std::string &intermed);
extern bool pxReadLine(wxInputStream &input, std::string &dest);
extern void pxWriteLine(wxOutputStream &output);
extern void pxWriteLine(wxOutputStream &output, const wxString &text);
extern void pxWriteMultiline(wxOutputStream &output, const wxString &src);

File diff suppressed because it is too large Load Diff

View File

@ -35,101 +35,124 @@
// Basic functions.
EXPORT_C_(s32) CDVDinit();
EXPORT_C_(s32) CDVDopen(void *pDisplay, const char* pTitleFilename);
EXPORT_C_(void) CDVDclose();
EXPORT_C_(void) CDVDshutdown();
EXPORT_C_(s32) CDVDreadTrack(u32 lsn, int mode);
EXPORT_C_(s32)
CDVDinit();
EXPORT_C_(s32)
CDVDopen(void *pDisplay, const char *pTitleFilename);
EXPORT_C_(void)
CDVDclose();
EXPORT_C_(void)
CDVDshutdown();
EXPORT_C_(s32)
CDVDreadTrack(u32 lsn, int mode);
// return can be NULL (for async modes)
EXPORT_C_(u8*) CDVDgetBuffer();
EXPORT_C_(u8 *)
CDVDgetBuffer();
EXPORT_C_(s32) CDVDreadSubQ(u32 lsn, cdvdSubQ* subq);//read subq from disc (only cds have subq data)
EXPORT_C_(s32) CDVDgetTN(cdvdTN *Buffer); //disk information
EXPORT_C_(s32) CDVDgetTD(u8 Track, cdvdTD *Buffer); //track info: min,sec,frame,type
EXPORT_C_(s32) CDVDgetTOC(void* toc); //gets ps2 style toc from disc
EXPORT_C_(s32) CDVDgetDiskType(); //CDVD_TYPE_xxxx
EXPORT_C_(s32) CDVDgetTrayStatus(); //CDVD_TRAY_xxxx
EXPORT_C_(s32) CDVDctrlTrayOpen(); //open disc tray
EXPORT_C_(s32) CDVDctrlTrayClose(); //close disc tray
EXPORT_C_(s32)
CDVDreadSubQ(u32 lsn, cdvdSubQ *subq); //read subq from disc (only cds have subq data)
EXPORT_C_(s32)
CDVDgetTN(cdvdTN *Buffer); //disk information
EXPORT_C_(s32)
CDVDgetTD(u8 Track, cdvdTD *Buffer); //track info: min,sec,frame,type
EXPORT_C_(s32)
CDVDgetTOC(void *toc); //gets ps2 style toc from disc
EXPORT_C_(s32)
CDVDgetDiskType(); //CDVD_TYPE_xxxx
EXPORT_C_(s32)
CDVDgetTrayStatus(); //CDVD_TRAY_xxxx
EXPORT_C_(s32)
CDVDctrlTrayOpen(); //open disc tray
EXPORT_C_(s32)
CDVDctrlTrayClose(); //close disc tray
// Extended functions
EXPORT_C_(void) CDVDkeyEvent(keyEvent *ev);
EXPORT_C_(void) CDVDconfigure();
EXPORT_C_(s32) CDVDfreeze(u8 mode, freezeData *data);
EXPORT_C_(void) CDVDabout();
EXPORT_C_(s32) CDVDtest();
EXPORT_C_(void) CDVDnewDiskCB(void (*callback)());
EXPORT_C_(void)
CDVDkeyEvent(keyEvent *ev);
EXPORT_C_(void)
CDVDconfigure();
EXPORT_C_(s32)
CDVDfreeze(u8 mode, freezeData *data);
EXPORT_C_(void)
CDVDabout();
EXPORT_C_(s32)
CDVDtest();
EXPORT_C_(void)
CDVDnewDiskCB(void (*callback)());
typedef struct _cdvdSubQ {
u8 ctrl:4; // control and mode bits
u8 mode:4; // control and mode bits
u8 trackNum; // current track number (1 to 99)
u8 trackIndex; // current index within track (0 to 99)
u8 trackM; // current minute location on the disc (BCD encoded)
u8 trackS; // current sector location on the disc (BCD encoded)
u8 trackF; // current frame location on the disc (BCD encoded)
u8 pad; // unused
u8 discM; // current minute offset from first track (BCD encoded)
u8 discS; // current sector offset from first track (BCD encoded)
u8 discF; // current frame offset from first track (BCD encoded)
typedef struct _cdvdSubQ
{
u8 ctrl : 4; // control and mode bits
u8 mode : 4; // control and mode bits
u8 trackNum; // current track number (1 to 99)
u8 trackIndex; // current index within track (0 to 99)
u8 trackM; // current minute location on the disc (BCD encoded)
u8 trackS; // current sector location on the disc (BCD encoded)
u8 trackF; // current frame location on the disc (BCD encoded)
u8 pad; // unused
u8 discM; // current minute offset from first track (BCD encoded)
u8 discS; // current sector offset from first track (BCD encoded)
u8 discF; // current frame offset from first track (BCD encoded)
} cdvdSubQ;
typedef struct _cdvdTD { // NOT bcd coded
u32 lsn;
u8 type;
typedef struct _cdvdTD
{ // NOT bcd coded
u32 lsn;
u8 type;
} cdvdTD;
typedef struct _cdvdTN {
u8 strack; //number of the first track (usually 1)
u8 etrack; //number of the last track
typedef struct _cdvdTN
{
u8 strack; //number of the first track (usually 1)
u8 etrack; //number of the last track
} cdvdTN;
// CDVDreadTrack mode values:
enum {
CDVD_MODE_2352 0, // full 2352 bytes
CDVD_MODE_2340 1, // skip sync (12) bytes
CDVD_MODE_2328 2, // skip sync+head+sub (24) bytes
CDVD_MODE_2048 3, // skip sync+head+sub (24) bytes
CDVD_MODE_2368 4 // full 2352 bytes + 16 subq
CDVD_MODE_2352 0, // full 2352 bytes
CDVD_MODE_2340 1, // skip sync (12) bytes
CDVD_MODE_2328 2, // skip sync+head+sub (24) bytes
CDVD_MODE_2048 3, // skip sync+head+sub (24) bytes
CDVD_MODE_2368 4 // full 2352 bytes + 16 subq
} TrackModes
// CDVDgetDiskType returns:
enum {
CDVD_TYPE_ILLEGAL = 0xff, // Illegal Disc
CDVD_TYPE_DVDV = 0xfe, // DVD Video
CDVD_TYPE_CDDA = 0xfd, // Audio CD
CDVD_TYPE_PS2DVD = 0x14, // PS2 DVD
CDVD_TYPE_PS2CDDA = 0x13, // PS2 CD (with audio)
CDVD_TYPE_PS2CD = 0x12, // PS2 CD
CDVD_TYPE_PSCDDA = 0x11, // PS CD (with audio)
CDVD_TYPE_PSCD = 0x10, // PS CD
CDVD_TYPE_UNKNOWN = 0x05, // Unknown
CDVD_TYPE_DETCTDVDD = 0x04, // Detecting Dvd Dual Sided
CDVD_TYPE_DETCTDVDS = 0x03, // Detecting Dvd Single Sided
CDVD_TYPE_DETCTCD = 0x02, // Detecting Cd
CDVD_TYPE_DETCT = 0x01, // Detecting
CDVD_TYPE_NODISC = 0x00 // No Disc
} DiskType;
// CDVDgetDiskType returns:
enum {
CDVD_TYPE_ILLEGAL = 0xff, // Illegal Disc
CDVD_TYPE_DVDV = 0xfe, // DVD Video
CDVD_TYPE_CDDA = 0xfd, // Audio CD
CDVD_TYPE_PS2DVD = 0x14, // PS2 DVD
CDVD_TYPE_PS2CDDA = 0x13, // PS2 CD (with audio)
CDVD_TYPE_PS2CD = 0x12, // PS2 CD
CDVD_TYPE_PSCDDA = 0x11, // PS CD (with audio)
CDVD_TYPE_PSCD = 0x10, // PS CD
CDVD_TYPE_UNKNOWN = 0x05, // Unknown
CDVD_TYPE_DETCTDVDD = 0x04, // Detecting Dvd Dual Sided
CDVD_TYPE_DETCTDVDS = 0x03, // Detecting Dvd Single Sided
CDVD_TYPE_DETCTCD = 0x02, // Detecting Cd
CDVD_TYPE_DETCT = 0x01, // Detecting
CDVD_TYPE_NODISC = 0x00 // No Disc
} DiskType;
// CDVDgetTrayStatus returns:
enum {
CDVD_TRAY_CLOSE = 0x00,
CDVD_TRAY_OPEN = 0x01
CDVD_TRAY_CLOSE = 0x00,
CDVD_TRAY_OPEN = 0x01
} TrayStatus;
// cdvdTD.type (track types for cds)
enum {
CDVD_AUDIO_TRACK = 0x01,
CDVD_MODE1_TRACK = 0x41,
CDVD_MODE2_TRACK = 0x61
CDVD_AUDIO_TRACK = 0x01,
CDVD_MODE1_TRACK = 0x41,
CDVD_MODE2_TRACK = 0x61
} CDVDTDType;
enum {
CDVD_AUDIO_MASK = 0x00,
CDVD_DATA_MASK = 0x40
// CDROM_DATA_TRACK 0x04 //do not enable this! (from linux kernel)
CDVD_AUDIO_MASK = 0x00,
CDVD_DATA_MASK = 0x40
// CDROM_DATA_TRACK 0x04 //do not enable this! (from linux kernel)
} CDVD_Masks;
#endif // __CDVDAPI_H__

View File

@ -32,37 +32,56 @@
#include "Pcsx2Api.h"
typedef void (*DEV9callback)(int cycles);
typedef int (*DEV9handler)(void);
typedef int (*DEV9handler)(void);
// Basic functions.
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
EXPORT_C_(s32) DEV9init();
EXPORT_C_(s32)
DEV9init();
// pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) DEV9open(void *pDisplay);
EXPORT_C_(void) DEV9close();
EXPORT_C_(void) DEV9shutdown();
EXPORT_C_(u8) DEV9read8(u32 addr);
EXPORT_C_(u16) DEV9read16(u32 addr);
EXPORT_C_(u32) DEV9read32(u32 addr);
EXPORT_C_(void) DEV9write8(u32 addr, u8 value);
EXPORT_C_(void) DEV9write16(u32 addr, u16 value);
EXPORT_C_(void) DEV9write32(u32 addr, u32 value);
EXPORT_C_(void) DEV9readDMA8Mem(u32 *pMem, int size);
EXPORT_C_(void) DEV9writeDMA8Mem(u32 *pMem, int size);
EXPORT_C_(s32)
DEV9open(void *pDisplay);
EXPORT_C_(void)
DEV9close();
EXPORT_C_(void)
DEV9shutdown();
EXPORT_C_(u8)
DEV9read8(u32 addr);
EXPORT_C_(u16)
DEV9read16(u32 addr);
EXPORT_C_(u32)
DEV9read32(u32 addr);
EXPORT_C_(void)
DEV9write8(u32 addr, u8 value);
EXPORT_C_(void)
DEV9write16(u32 addr, u16 value);
EXPORT_C_(void)
DEV9write32(u32 addr, u32 value);
EXPORT_C_(void)
DEV9readDMA8Mem(u32 *pMem, int size);
EXPORT_C_(void)
DEV9writeDMA8Mem(u32 *pMem, int size);
// cycles = IOP cycles before calling callback,
// if callback returns 1 the irq is triggered, else not
EXPORT_C_(void) DEV9irqCallback(DEV9callback callback);
EXPORT_C_(DEV9handler) DEV9irqHandler(void);
EXPORT_C_(void)
DEV9irqCallback(DEV9callback callback);
EXPORT_C_(DEV9handler)
DEV9irqHandler(void);
// Extended functions
EXPORT_C_(void) DEV9keyEvent(keyEvent *ev);
EXPORT_C_(s32) DEV9freeze(u8 mode, freezeData *data);
EXPORT_C_(void) DEV9configure();
EXPORT_C_(void) DEV9about();
EXPORT_C_(s32) DEV9test();
EXPORT_C_(void)
DEV9keyEvent(keyEvent *ev);
EXPORT_C_(s32)
DEV9freeze(u8 mode, freezeData *data);
EXPORT_C_(void)
DEV9configure();
EXPORT_C_(void)
DEV9about();
EXPORT_C_(s32)
DEV9test();
#endif // __DEV9API_H__

View File

@ -37,22 +37,34 @@
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
EXPORT_C_(s32) FWinit();
EXPORT_C_(s32)
FWinit();
// pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) FWopen(void *pDisplay);
EXPORT_C_(void) FWclose();
EXPORT_C_(void) FWshutdown();
EXPORT_C_(u32) FWread32(u32 addr);
EXPORT_C_(void) FWwrite32(u32 addr, u32 value);
EXPORT_C_(void) FWirqCallback(void (*callback)());
EXPORT_C_(s32)
FWopen(void *pDisplay);
EXPORT_C_(void)
FWclose();
EXPORT_C_(void)
FWshutdown();
EXPORT_C_(u32)
FWread32(u32 addr);
EXPORT_C_(void)
FWwrite32(u32 addr, u32 value);
EXPORT_C_(void)
FWirqCallback(void (*callback)());
// Extended functions
EXPORT_C_(void) FWkeyEvent(keyEvent *ev);
EXPORT_C_(s32) FWfreeze(u8 mode, freezeData *data);
EXPORT_C_(void) FWconfigure();
EXPORT_C_(void) FWabout();
EXPORT_C_(s32) FWtest();
EXPORT_C_(void)
FWkeyEvent(keyEvent *ev);
EXPORT_C_(s32)
FWfreeze(u8 mode, freezeData *data);
EXPORT_C_(void)
FWconfigure();
EXPORT_C_(void)
FWabout();
EXPORT_C_(s32)
FWtest();
#endif
#endif // __USBAPI_H__

View File

@ -31,55 +31,86 @@
#include "Pcsx2Api.h"
typedef struct _GSdriverInfo {
char name[8];
void *common;
typedef struct _GSdriverInfo
{
char name[8];
void *common;
} GSdriverInfo;
// Basic functions.
EXPORT_C_(s32) GSinit();
EXPORT_C_(s32)
GSinit();
// pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) GSopen(void *pDisplay, char *Title, bool multithread);
EXPORT_C_(void) GSclose();
EXPORT_C_(void) GSshutdown();
EXPORT_C_(void) GSvsync(int field);
EXPORT_C_(void) GSgifTransfer1(u32 *pMem, u32 addr);
EXPORT_C_(void) GSgifTransfer2(u32 *pMem, u32 size);
EXPORT_C_(void) GSgifTransfer3(u32 *pMem, u32 size);
EXPORT_C_(void) GSgetLastTag(u64* ptag); // returns the last tag processed (64 bits)
EXPORT_C_(void) GSgifSoftReset(u32 mask);
EXPORT_C_(void) GSreadFIFO(u64 *mem);
EXPORT_C_(void) GSreadFIFO2(u64 *mem, int qwc);
EXPORT_C_(s32)
GSopen(void *pDisplay, char *Title, bool multithread);
EXPORT_C_(void)
GSclose();
EXPORT_C_(void)
GSshutdown();
EXPORT_C_(void)
GSvsync(int field);
EXPORT_C_(void)
GSgifTransfer1(u32 *pMem, u32 addr);
EXPORT_C_(void)
GSgifTransfer2(u32 *pMem, u32 size);
EXPORT_C_(void)
GSgifTransfer3(u32 *pMem, u32 size);
EXPORT_C_(void)
GSgetLastTag(u64 *ptag); // returns the last tag processed (64 bits)
EXPORT_C_(void)
GSgifSoftReset(u32 mask);
EXPORT_C_(void)
GSreadFIFO(u64 *mem);
EXPORT_C_(void)
GSreadFIFO2(u64 *mem, int qwc);
// Extended functions
// GSkeyEvent gets called when there is a keyEvent from the PAD plugin
EXPORT_C_(void) GSkeyEvent(keyEvent *ev);
EXPORT_C_(void) GSchangeSaveState(s32 state, const char* filename);
EXPORT_C_(void) GSmakeSnapshot(char *path);
EXPORT_C_(void) GSmakeSnapshot2(char *pathname, int* snapdone, int savejpg);
EXPORT_C_(void) GSirqCallback(void (*callback)());
EXPORT_C_(void) CALLBACK GSprintf(s32 timeout, char *fmt, ...);
EXPORT_C_(void) GSsetBaseMem(void*);
EXPORT_C_(void) GSsetGameCRC(s32 crc, s32 gameoptions);
EXPORT_C_(void)
GSkeyEvent(keyEvent *ev);
EXPORT_C_(void)
GSchangeSaveState(s32 state, const char *filename);
EXPORT_C_(void)
GSmakeSnapshot(char *path);
EXPORT_C_(void)
GSmakeSnapshot2(char *pathname, int *snapdone, int savejpg);
EXPORT_C_(void)
GSirqCallback(void (*callback)());
EXPORT_C_(void)
CALLBACK GSprintf(s32 timeout, char *fmt, ...);
EXPORT_C_(void)
GSsetBaseMem(void *);
EXPORT_C_(void)
GSsetGameCRC(s32 crc, s32 gameoptions);
// controls frame skipping in the GS, if this routine isn't present, frame skipping won't be done
EXPORT_C_(void) GSsetFrameSkip(int frameskip);
EXPORT_C_(void)
GSsetFrameSkip(int frameskip);
// if start is true, starts recording spu2 data, else stops
// returns true if successful
// for now, pData is not used
EXPORT_C_(bool) GSsetupRecording(bool start);
EXPORT_C_(bool)
GSsetupRecording(bool start);
EXPORT_C_(void) GSreset();
EXPORT_C_(void) GSwriteCSR(u32 value);
EXPORT_C_(void ) GSgetDriverInfo(GSdriverInfo *info);
EXPORT_C_(void)
GSreset();
EXPORT_C_(void)
GSwriteCSR(u32 value);
EXPORT_C_(void)
GSgetDriverInfo(GSdriverInfo *info);
#ifdef _WIN32
EXPORT_C_(s32) CALLBACK GSsetWindowInfo(winInfo *info);
EXPORT_C_(s32)
CALLBACK GSsetWindowInfo(winInfo *info);
#endif
EXPORT_C_(s32) GSfreeze(u8 mode, freezeData *data);
EXPORT_C_(void) GSconfigure();
EXPORT_C_(void) GSabout();
EXPORT_C_(s32) GStest();
EXPORT_C_(s32)
GSfreeze(u8 mode, freezeData *data);
EXPORT_C_(void)
GSconfigure();
EXPORT_C_(void)
GSabout();
EXPORT_C_(s32)
GStest();
#endif // __GSAPI_H__

View File

@ -35,19 +35,27 @@
/* So obsolete that everyone uses it. */
// Basic functions.
EXPORT_C_(s32) PADinit(u32 flags);
EXPORT_C_(s32)
PADinit(u32 flags);
// pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) PADopen(void *pDisplay);
EXPORT_C_(void) PADclose();
EXPORT_C_(void) PADshutdown();
EXPORT_C_(s32)
PADopen(void *pDisplay);
EXPORT_C_(void)
PADclose();
EXPORT_C_(void)
PADshutdown();
// PADkeyEvent is called every vsync (return NULL if no event)
EXPORT_C_(keyEvent*) PADkeyEvent();
EXPORT_C_(u8) PADstartPoll(u8 pad);
EXPORT_C_(u8) PADpoll(u8 value);
EXPORT_C_(keyEvent *)
PADkeyEvent();
EXPORT_C_(u8)
PADstartPoll(u8 pad);
EXPORT_C_(u8)
PADpoll(u8 value);
// returns: 1 if supported pad1
// 2 if supported pad2
// 3 if both are supported
EXPORT_C_(u8) PADquery();
EXPORT_C_(u8)
PADquery();
// call to give a hint to the PAD plugin to query for the keyboard state. A
// good plugin will query the OS for keyboard state ONLY in this function.
@ -56,25 +64,33 @@ EXPORT_C_(u8) PADquery();
// the window (and input). Note that PADupdate can be called from a different
// thread than the other functions, so mutex or other multithreading primitives
// have to be added to maintain data integrity.
EXPORT_C_(void) PADupdate(u8 pad);
EXPORT_C_(void)
PADupdate(u8 pad);
// Extended functions
EXPORT_C_(void) PADgsDriverInfo(GSdriverInfo *info);
EXPORT_C_(s32) PADfreeze(u8 mode, freezeData *data);
EXPORT_C_(void)
PADgsDriverInfo(GSdriverInfo *info);
EXPORT_C_(s32)
PADfreeze(u8 mode, freezeData *data);
// Returns 1 if the pad plugin wants a multitap on the specified port.
// 0 otherwise.
EXPORT_C_(s32) PADqueryMtap(u8 port);
EXPORT_C_(s32)
PADqueryMtap(u8 port);
// Sets the active pad slot for the specified port.
// Both numbers are 1-based indices. Should return 0 if there's no
// pad on the specified slot. Even if PADqueryMtap(port) returns 0,
// should handle this properly for slot != 1, so emulator can allow
// Multitap to be enabled/disabled elsewhere.
EXPORT_C_(s32) PADsetSlot(u8 port, u8 slot);
EXPORT_C_(s32)
PADsetSlot(u8 port, u8 slot);
EXPORT_C_(void) PADconfigure();
EXPORT_C_(void) PADabout();
EXPORT_C_(s32) PADtest();
EXPORT_C_(void)
PADconfigure();
EXPORT_C_(void)
PADabout();
EXPORT_C_(s32)
PADtest();
#endif // __PADAPI_H__

View File

@ -38,49 +38,61 @@
// MTAP SIO plugins should ignore slot values on startPoll, as should RMs (probably).
// Port isn't strictly necessary, but doesn't hurt.
typedef int (CALLBACK * SIOchangeSlotCB)(int port, int slot);
typedef int(CALLBACK *SIOchangeSlotCB)(int port, int slot);
// Basic functions.
// Types is an or-ed combination of SioTypes to initialize. It'd probably be simplest
// just to make each SIO plugin support only one type, for simplicity.
// SIOchangeSlotCB should *only* be called by MTAP plugins.
EXPORT_C_(s32) SIOinit(int types, SIOchangeSlotCB f);
EXPORT_C_(s32)
SIOinit(int types, SIOchangeSlotCB f);
// Single plugin can only be PAD, MTAP, RM, or MC. Only load one plugin of each type,
// but not both a PAD and MTAP. Simplifies plugin selection and interface, as well
// as API.
// pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) SIOopen(void *pDisplay);
EXPORT_C_(void) SIOclose();
EXPORT_C_(void) SIOshutdown();
EXPORT_C_(s32)
SIOopen(void *pDisplay);
EXPORT_C_(void)
SIOclose();
EXPORT_C_(void)
SIOshutdown();
// Returns 0 if device doesn't exist. Means old pad plugins can just say nothing
// connected to other slots, and SIOpoll won't be called on those slots, ideally.
EXPORT_C_(s32) SIOstartPoll(u8 deviceType, u32 port, u32 slot, u8 *returnValue);
EXPORT_C_(s32)
SIOstartPoll(u8 deviceType, u32 port, u32 slot, u8 *returnValue);
// Returns 0 on the last output byte.
EXPORT_C_(s32) SIOpoll(u8 value, u8 *returnValue);
EXPORT_C_(s32)
SIOpoll(u8 value, u8 *returnValue);
// returns: SIO_TYPE_{PAD,MTAP,RM,MC}
EXPORT_C_(u32) SIOquery();
EXPORT_C_(u32)
SIOquery();
// extended funcs
EXPORT_C_(void) SIOconfigure();
EXPORT_C_(keyEvent*) CALLBACK SIOkeyEvent();
EXPORT_C_(void)
SIOconfigure();
EXPORT_C_(keyEvent *)
CALLBACK SIOkeyEvent();
// Save one type at a time. If a plugin supports all 4 types,
// should expect 4 calls. Increases savestate compatibility.
EXPORT_C_(s32) SIOfreeze(u8 mode, freezeData *data, int type);
EXPORT_C_(void) SIOabout();
EXPORT_C_(s32) SIOtest();
EXPORT_C_(s32)
SIOfreeze(u8 mode, freezeData *data, int type);
EXPORT_C_(void)
SIOabout();
EXPORT_C_(s32)
SIOtest();
enum {
SIO_TYPE_PAD = 0x00000001,
SIO_TYPE_MTAP = 0x00000004,
SIO_TYPE_RM = 0x00000040,
SIO_TYPE_MC = 0x00000100
SIO_TYPE_PAD = 0x00000001,
SIO_TYPE_MTAP = 0x00000004,
SIO_TYPE_RM = 0x00000040,
SIO_TYPE_MC = 0x00000100
} SioTypes;
#endif // __SIOAPI_H__

View File

@ -31,47 +31,74 @@
#include "Pcsx2Api.h"
EXPORT_C_(s32) SPU2init();
EXPORT_C_(s32)
SPU2init();
// pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) SPU2open(void *pDisplay);
EXPORT_C_(void) SPU2close();
EXPORT_C_(void) SPU2shutdown();
EXPORT_C_(void) SPU2write(u32 mem, u16 value);
EXPORT_C_(u16) SPU2read(u32 mem);
EXPORT_C_(s32)
SPU2open(void *pDisplay);
EXPORT_C_(void)
SPU2close();
EXPORT_C_(void)
SPU2shutdown();
EXPORT_C_(void)
SPU2write(u32 mem, u16 value);
EXPORT_C_(u16)
SPU2read(u32 mem);
// The following calls are depreciated.
EXPORT_C_(void) SPU2readDMA4Mem(u16 *pMem, u32 size);
EXPORT_C_(void) SPU2readDMA7Mem(u16 *pMem, u32 size);
EXPORT_C_(void) SPU2writeDMA4Mem(u16 *pMem, u32 size);
EXPORT_C_(void) SPU2writeDMA7Mem(u16 *pMem, u32 size);
EXPORT_C_(void) SPU2interruptDMA4();
EXPORT_C_(void) SPU2interruptDMA7();
EXPORT_C_(void)
SPU2readDMA4Mem(u16 *pMem, u32 size);
EXPORT_C_(void)
SPU2readDMA7Mem(u16 *pMem, u32 size);
EXPORT_C_(void)
SPU2writeDMA4Mem(u16 *pMem, u32 size);
EXPORT_C_(void)
SPU2writeDMA7Mem(u16 *pMem, u32 size);
EXPORT_C_(void)
SPU2interruptDMA4();
EXPORT_C_(void)
SPU2interruptDMA7();
// These calls replace the calls above.
EXPORT_C_(void) SPU2readDMAMem(u16 *pMem, u32 size, u8 core);
EXPORT_C_(void) SPU2writeDMAMem(u16 *pMem, u32 size, u8 core);
EXPORT_C_(void) SPU2interruptDMA(u8 core);
EXPORT_C_(void)
SPU2readDMAMem(u16 *pMem, u32 size, u8 core);
EXPORT_C_(void)
SPU2writeDMAMem(u16 *pMem, u32 size, u8 core);
EXPORT_C_(void)
SPU2interruptDMA(u8 core);
// all addresses passed by dma will be pointers to the array starting at baseaddr
// This function is necessary to successfully save and reload the spu2 state
EXPORT_C_(void) SPU2setDMABaseAddr(uptr baseaddr);
EXPORT_C_(void)
SPU2setDMABaseAddr(uptr baseaddr);
EXPORT_C_(u32) SPU2ReadMemAddr(u8 core);
EXPORT_C_(void) SPU2WriteMemAddr(u8 core,u32 value);
EXPORT_C_(void) SPU2irqCallback(void (*SPU2callback)(),void (*DMA4callback)(),void (*DMA7callback)());
EXPORT_C_(u32)
SPU2ReadMemAddr(u8 core);
EXPORT_C_(void)
SPU2WriteMemAddr(u8 core, u32 value);
EXPORT_C_(void)
SPU2irqCallback(void (*SPU2callback)(), void (*DMA4callback)(), void (*DMA7callback)());
// extended funcs
// if start is true, starts recording spu2 data, else stops
// returns true if successful
EXPORT_C_(bool) SPU2setupRecording(bool start);
EXPORT_C_(bool)
SPU2setupRecording(bool start);
EXPORT_C_(void) SPU2keyEvent(keyEvent *ev);
EXPORT_C_(void) SPU2setClockPtr(u32* ptr);
EXPORT_C_(void) SPU2async(u32 cycles);
EXPORT_C_(s32) SPU2freeze(u8 mode, freezeData *data);
EXPORT_C_(void) SPU2configure();
EXPORT_C_(void) SPU2about();
EXPORT_C_(s32) SPU2test();
EXPORT_C_(void)
SPU2keyEvent(keyEvent *ev);
EXPORT_C_(void)
SPU2setClockPtr(u32 *ptr);
EXPORT_C_(void)
SPU2async(u32 cycles);
EXPORT_C_(s32)
SPU2freeze(u8 mode, freezeData *data);
EXPORT_C_(void)
SPU2configure();
EXPORT_C_(void)
SPU2about();
EXPORT_C_(s32)
SPU2test();
#endif

View File

@ -32,34 +32,53 @@
#include "Pcsx2Api.h"
typedef void (*USBcallback)(int cycles);
typedef int (*USBhandler)(void);
typedef int (*USBhandler)(void);
// Basic functions.
EXPORT_C_(s32) USBinit();
EXPORT_C_(s32)
USBinit();
// pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) USBopen(void *pDisplay);
EXPORT_C_(void) USBclose();
EXPORT_C_(void) USBshutdown();
EXPORT_C_(u8) USBread8(u32 addr);
EXPORT_C_(u16) USBread16(u32 addr);
EXPORT_C_(u32) USBread32(u32 addr);
EXPORT_C_(void) USBwrite8(u32 addr, u8 value);
EXPORT_C_(void) USBwrite16(u32 addr, u16 value);
EXPORT_C_(void) USBwrite32(u32 addr, u32 value);
EXPORT_C_(void) USBasync(u32 cycles);
EXPORT_C_(s32)
USBopen(void *pDisplay);
EXPORT_C_(void)
USBclose();
EXPORT_C_(void)
USBshutdown();
EXPORT_C_(u8)
USBread8(u32 addr);
EXPORT_C_(u16)
USBread16(u32 addr);
EXPORT_C_(u32)
USBread32(u32 addr);
EXPORT_C_(void)
USBwrite8(u32 addr, u8 value);
EXPORT_C_(void)
USBwrite16(u32 addr, u16 value);
EXPORT_C_(void)
USBwrite32(u32 addr, u32 value);
EXPORT_C_(void)
USBasync(u32 cycles);
// cycles = IOP cycles before calling callback,
// if callback returns 1 the irq is triggered, else not
EXPORT_C_(void) USBirqCallback(USBcallback callback);
EXPORT_C_(USBhandler) USBirqHandler(void);
EXPORT_C_(void) USBsetRAM(void *mem);
EXPORT_C_(void)
USBirqCallback(USBcallback callback);
EXPORT_C_(USBhandler)
USBirqHandler(void);
EXPORT_C_(void)
USBsetRAM(void *mem);
// Extended functions
EXPORT_C_(void) USBkeyEvent(keyEvent *ev);
EXPORT_C_(s32) USBfreeze(u8 mode, freezeData *data);
EXPORT_C_(void) USBconfigure();
EXPORT_C_(void) USBabout();
EXPORT_C_(s32) USBtest();
EXPORT_C_(void)
USBkeyEvent(keyEvent *ev);
EXPORT_C_(s32)
USBfreeze(u8 mode, freezeData *data);
EXPORT_C_(void)
USBconfigure();
EXPORT_C_(void)
USBabout();
EXPORT_C_(s32)
USBtest();
#endif // __USBAPI_H__

View File

@ -17,21 +17,22 @@
// Implement BMI1/BMI2 instruction set
namespace x86Emitter {
namespace x86Emitter
{
struct xImplBMI_RVM
{
u8 Prefix;
u8 MbPrefix;
u8 Opcode;
struct xImplBMI_RVM
{
u8 Prefix;
u8 MbPrefix;
u8 Opcode;
// RVM
// MULX Unsigned multiply without affecting flags, and arbitrary destination registers
// PDEP Parallel bits deposit
// PEXT Parallel bits extract
// ANDN Logical and not ~x & y
void operator()( const xRegisterInt& to, const xRegisterInt& from1, const xRegisterInt& from2) const;
void operator()( const xRegisterInt& to, const xRegisterInt& from1, const xIndirectVoid& from2) const;
// RVM
// MULX Unsigned multiply without affecting flags, and arbitrary destination registers
// PDEP Parallel bits deposit
// PEXT Parallel bits extract
// ANDN Logical and not ~x & y
void operator()(const xRegisterInt &to, const xRegisterInt &from1, const xRegisterInt &from2) const;
void operator()(const xRegisterInt &to, const xRegisterInt &from1, const xIndirectVoid &from2) const;
#if 0
// RMV
@ -56,6 +57,5 @@ namespace x86Emitter {
void operator()( const xRegisterInt& to, const xRegisterInt& from, u8 imm) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& from, u8 imm) const;
#endif
};
};
}

View File

@ -15,7 +15,8 @@
#pragma once
namespace x86Emitter {
namespace x86Emitter
{
// Implementations here cover SHLD and SHRD.
@ -30,14 +31,14 @@ namespace x86Emitter {
//
struct xImpl_DwordShift
{
u16 OpcodeBase;
u16 OpcodeBase;
void operator()( const xRegister16or32or64& to, const xRegister16or32or64& from, const xRegisterCL& clreg ) const;
void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from, const xRegisterCL &clreg) const;
void operator()( const xRegister16or32or64& to, const xRegister16or32or64& from, u8 shiftcnt ) const;
void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from, u8 shiftcnt) const;
void operator()( const xIndirectVoid& dest,const xRegister16or32or64& from, const xRegisterCL& clreg ) const;
void operator()( const xIndirectVoid& dest,const xRegister16or32or64& from, u8 shiftcnt ) const;
void operator()(const xIndirectVoid &dest, const xRegister16or32or64 &from, const xRegisterCL &clreg) const;
void operator()(const xIndirectVoid &dest, const xRegister16or32or64 &from, u8 shiftcnt) const;
};
} // End namespace x86Emitter
} // End namespace x86Emitter

View File

@ -15,35 +15,35 @@
#pragma once
namespace x86Emitter {
enum G1Type
namespace x86Emitter
{
G1Type_ADD=0,
G1Type_OR,
G1Type_ADC,
G1Type_SBB,
G1Type_AND,
G1Type_SUB,
G1Type_XOR,
G1Type_CMP
enum G1Type {
G1Type_ADD = 0,
G1Type_OR,
G1Type_ADC,
G1Type_SBB,
G1Type_AND,
G1Type_SUB,
G1Type_XOR,
G1Type_CMP
};
extern void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, const xRegisterInt& from );
extern void _g1_EmitOp(G1Type InstType, const xRegisterInt &to, const xRegisterInt &from);
// --------------------------------------------------------------------------------------
// xImpl_Group1
// --------------------------------------------------------------------------------------
struct xImpl_Group1
{
G1Type InstType;
G1Type InstType;
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const;
void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const;
void operator()( const xRegisterInt& to, int imm ) const;
void operator()( const xIndirect64orLess& to, int imm ) const;
void operator()(const xIndirectVoid &to, const xRegisterInt &from) const;
void operator()(const xRegisterInt &to, const xIndirectVoid &from) const;
void operator()(const xRegisterInt &to, int imm) const;
void operator()(const xIndirect64orLess &to, int imm) const;
#if 0
// ------------------------------------------------------------------------
@ -87,18 +87,18 @@ struct xImpl_Group1
//
struct xImpl_G1Logic
{
G1Type InstType;
G1Type InstType;
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const;
void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const;
void operator()( const xRegisterInt& to, int imm ) const;
void operator()(const xIndirectVoid &to, const xRegisterInt &from) const;
void operator()(const xRegisterInt &to, const xIndirectVoid &from) const;
void operator()(const xRegisterInt &to, int imm) const;
void operator()( const xIndirect64orLess& to, int imm ) const;
void operator()(const xIndirect64orLess &to, int imm) const;
xImplSimd_DestRegSSE PS; // packed single precision
xImplSimd_DestRegSSE PD; // packed double precision
xImplSimd_DestRegSSE PS; // packed single precision
xImplSimd_DestRegSSE PD; // packed double precision
};
// ------------------------------------------------------------------------
@ -106,38 +106,37 @@ struct xImpl_G1Logic
//
struct xImpl_G1Arith
{
G1Type InstType;
G1Type InstType;
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const;
void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const;
void operator()( const xRegisterInt& to, int imm ) const;
void operator()(const xIndirectVoid &to, const xRegisterInt &from) const;
void operator()(const xRegisterInt &to, const xIndirectVoid &from) const;
void operator()(const xRegisterInt &to, int imm) const;
void operator()( const xIndirect64orLess& to, int imm ) const;
void operator()(const xIndirect64orLess &to, int imm) const;
xImplSimd_DestRegSSE PS; // packed single precision
xImplSimd_DestRegSSE PD; // packed double precision
xImplSimd_DestRegSSE SS; // scalar single precision
xImplSimd_DestRegSSE SD; // scalar double precision
xImplSimd_DestRegSSE PS; // packed single precision
xImplSimd_DestRegSSE PD; // packed double precision
xImplSimd_DestRegSSE SS; // scalar single precision
xImplSimd_DestRegSSE SD; // scalar double precision
};
// ------------------------------------------------------------------------
struct xImpl_G1Compare
{
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const;
void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const;
void operator()( const xRegisterInt& to, int imm ) const;
void operator()(const xIndirectVoid &to, const xRegisterInt &from) const;
void operator()(const xRegisterInt &to, const xIndirectVoid &from) const;
void operator()(const xRegisterInt &to, int imm) const;
void operator()( const xIndirect64orLess& to, int imm ) const;
void operator()(const xIndirect64orLess &to, int imm) const;
xImplSimd_DestSSE_CmpImm PS;
xImplSimd_DestSSE_CmpImm PD;
xImplSimd_DestSSE_CmpImm SS;
xImplSimd_DestSSE_CmpImm SD;
xImplSimd_DestSSE_CmpImm PS;
xImplSimd_DestSSE_CmpImm PD;
xImplSimd_DestSSE_CmpImm SS;
xImplSimd_DestSSE_CmpImm SD;
};
} // End namespace x86Emitter
} // End namespace x86Emitter

View File

@ -15,18 +15,18 @@
#pragma once
namespace x86Emitter {
enum G2Type
namespace x86Emitter
{
G2Type_ROL=0,
G2Type_ROR,
G2Type_RCL,
G2Type_RCR,
G2Type_SHL,
G2Type_SHR,
G2Type_Unused,
G2Type_SAR
enum G2Type {
G2Type_ROL = 0,
G2Type_ROR,
G2Type_RCL,
G2Type_RCR,
G2Type_SHL,
G2Type_SHR,
G2Type_Unused,
G2Type_SAR
};
// --------------------------------------------------------------------------------------
@ -38,12 +38,12 @@ enum G2Type
//
struct xImpl_Group2
{
G2Type InstType;
G2Type InstType;
void operator()( const xRegisterInt& to, const xRegisterCL& from ) const;
void operator()( const xIndirect64orLess& to, const xRegisterCL& from ) const;
void operator()( const xRegisterInt& to, u8 imm ) const;
void operator()( const xIndirect64orLess& to, u8 imm ) const;
void operator()(const xRegisterInt &to, const xRegisterCL &from) const;
void operator()(const xIndirect64orLess &to, const xRegisterCL &from) const;
void operator()(const xRegisterInt &to, u8 imm) const;
void operator()(const xIndirect64orLess &to, u8 imm) const;
#if 0
// ------------------------------------------------------------------------

View File

@ -15,16 +15,16 @@
#pragma once
namespace x86Emitter {
enum G3Type
namespace x86Emitter
{
G3Type_NOT = 2,
G3Type_NEG = 3,
G3Type_MUL = 4,
G3Type_iMUL = 5, // partial implementation, iMul has additional forms in ix86.cpp
G3Type_DIV = 6,
G3Type_iDIV = 7
enum G3Type {
G3Type_NOT = 2,
G3Type_NEG = 3,
G3Type_MUL = 4,
G3Type_iMUL = 5, // partial implementation, iMul has additional forms in ix86.cpp
G3Type_DIV = 6,
G3Type_iDIV = 7
};
// --------------------------------------------------------------------------------------
@ -32,10 +32,10 @@ enum G3Type
// --------------------------------------------------------------------------------------
struct xImpl_Group3
{
G3Type InstType;
G3Type InstType;
void operator()( const xRegisterInt& from ) const;
void operator()( const xIndirect64orLess& from ) const;
void operator()(const xRegisterInt &from) const;
void operator()(const xIndirect64orLess &from) const;
#if 0
template< typename T >
@ -53,16 +53,16 @@ struct xImpl_Group3
//
struct xImpl_MulDivBase
{
G3Type InstType;
u16 OpcodeSSE;
G3Type InstType;
u16 OpcodeSSE;
void operator()( const xRegisterInt& from ) const;
void operator()( const xIndirect64orLess& from ) const;
void operator()(const xRegisterInt &from) const;
void operator()(const xIndirect64orLess &from) const;
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD;
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD;
};
// --------------------------------------------------------------------------------------
@ -70,13 +70,13 @@ struct xImpl_MulDivBase
// --------------------------------------------------------------------------------------
struct xImpl_iDiv
{
void operator()( const xRegisterInt& from ) const;
void operator()( const xIndirect64orLess& from ) const;
void operator()(const xRegisterInt &from) const;
void operator()(const xIndirect64orLess &from) const;
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD;
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD;
};
// --------------------------------------------------------------------------------------
@ -85,25 +85,24 @@ struct xImpl_iDiv
//
struct xImpl_iMul
{
void operator()( const xRegisterInt& from ) const;
void operator()( const xIndirect64orLess& from ) const;
void operator()(const xRegisterInt &from) const;
void operator()(const xIndirect64orLess &from) const;
// The following iMul-specific forms are valid for 16 and 32 bit register operands only!
// The following iMul-specific forms are valid for 16 and 32 bit register operands only!
void operator()( const xRegister32& to, const xRegister32& from ) const;
void operator()( const xRegister32& to, const xIndirectVoid& src ) const;
void operator()( const xRegister16& to, const xRegister16& from ) const;
void operator()( const xRegister16& to, const xIndirectVoid& src ) const;
void operator()(const xRegister32 &to, const xRegister32 &from) const;
void operator()(const xRegister32 &to, const xIndirectVoid &src) const;
void operator()(const xRegister16 &to, const xRegister16 &from) const;
void operator()(const xRegister16 &to, const xIndirectVoid &src) const;
void operator()( const xRegister32& to, const xRegister32& from, s32 imm ) const;
void operator()( const xRegister32& to, const xIndirectVoid& from, s32 imm ) const;
void operator()( const xRegister16& to, const xRegister16& from, s16 imm ) const;
void operator()( const xRegister16& to, const xIndirectVoid& from, s16 imm ) const;
void operator()(const xRegister32 &to, const xRegister32 &from, s32 imm) const;
void operator()(const xRegister32 &to, const xIndirectVoid &from, s32 imm) const;
void operator()(const xRegister16 &to, const xRegister16 &from, s16 imm) const;
void operator()(const xRegister16 &to, const xIndirectVoid &from, s16 imm) const;
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD;
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD;
};
}

View File

@ -15,7 +15,8 @@
#pragma once
namespace x86Emitter {
namespace x86Emitter
{
// helpermess is currently broken >_<
@ -88,4 +89,4 @@ void _DoI_helpermess( const xImpl& helpme, const xDirectOrIndirect<T>& to, const
}
#endif
} // End namespace x86Emitter
} // End namespace x86Emitter

View File

@ -18,17 +18,18 @@
// Implementations found here: Increment and Decrement Instructions!
// (They're soooo lonely... but I dunno where else to stick this class!)
namespace x86Emitter {
namespace x86Emitter
{
// --------------------------------------------------------------------------------------
// xImpl_IncDec
// --------------------------------------------------------------------------------------
struct xImpl_IncDec
{
bool isDec;
bool isDec;
void operator()( const xRegisterInt& to ) const;
void operator()( const xIndirect64orLess& to ) const;
void operator()(const xRegisterInt &to) const;
void operator()(const xIndirect64orLess &to) const;
};
} // End namespace x86Emitter
} // End namespace x86Emitter

View File

@ -17,171 +17,170 @@
// Implementations found here: CALL and JMP! (unconditional only)
namespace x86Emitter {
namespace x86Emitter
{
extern void xJccKnownTarget( JccComparisonType comparison, const void* target, bool slideForward );
extern void xJccKnownTarget(JccComparisonType comparison, const void *target, bool slideForward);
// ------------------------------------------------------------------------
struct xImpl_JmpCall
{
bool isJmp;
bool isJmp;
void operator()( const xRegisterInt& absreg ) const;
void operator()( const xIndirect64orLess& src ) const;
void operator()(const xRegisterInt &absreg) const;
void operator()(const xIndirect64orLess &src) const;
// Special form for calling functions. This form automatically resolves the
// correct displacement based on the size of the instruction being generated.
void operator()( void* func ) const
{
if( isJmp )
xJccKnownTarget( Jcc_Unconditional, (void*)(uptr)func, false ); // double cast to/from (uptr) needed to appease GCC
else
{
// calls are relative to the instruction after this one, and length is
// always 5 bytes (16 bit calls are bad mojo, so no bother to do special logic).
// Special form for calling functions. This form automatically resolves the
// correct displacement based on the size of the instruction being generated.
void operator()(void *func) const
{
if (isJmp)
xJccKnownTarget(Jcc_Unconditional, (void *)(uptr)func, false); // double cast to/from (uptr) needed to appease GCC
else {
// calls are relative to the instruction after this one, and length is
// always 5 bytes (16 bit calls are bad mojo, so no bother to do special logic).
sptr dest = (sptr)func - ((sptr)xGetPtr() + 5);
xWrite8( 0xe8 );
xWrite32( dest );
}
}
sptr dest = (sptr)func - ((sptr)xGetPtr() + 5);
xWrite8(0xe8);
xWrite32(dest);
}
}
};
// yes it is awful. Due to template code is in a header with a nice circular dep.
extern const xImpl_Mov xMOV;
extern const xImpl_JmpCall xCALL;
extern const xImpl_Mov xMOV;
extern const xImpl_JmpCall xCALL;
struct xImpl_FastCall
{
// FIXME: current 64 bits is mostly a copy/past potentially it would require to push/pop
// some registers. But I think it is enough to handle the first call.
// FIXME: current 64 bits is mostly a copy/past potentially it would require to push/pop
// some registers. But I think it is enough to handle the first call.
// Type unsafety is nice
// Type unsafety is nice
#ifdef __x86_64__
#define XFASTCALL \
xCALL(f);
xCALL(f);
#define XFASTCALL1 \
xMOV(rdi, a1); \
xCALL(f);
xMOV(rdi, a1); \
xCALL(f);
#define XFASTCALL2 \
xMOV(rdi, a1); \
xMOV(rsi, a2); \
xCALL(f);
xMOV(rdi, a1); \
xMOV(rsi, a2); \
xCALL(f);
#else
#define XFASTCALL \
xCALL(f);
xCALL(f);
#define XFASTCALL1 \
xMOV(ecx, a1); \
xCALL(f);
xMOV(ecx, a1); \
xCALL(f);
#define XFASTCALL2 \
xMOV(ecx, a1); \
xMOV(edx, a2); \
xCALL(f);
xMOV(ecx, a1); \
xMOV(edx, a2); \
xCALL(f);
#endif
void operator()( void* f, const xRegisterLong& a1 = xEmptyReg, const xRegisterLong& a2 = xEmptyReg) const
{
void operator()(void *f, const xRegisterLong &a1 = xEmptyReg, const xRegisterLong &a2 = xEmptyReg) const
{
#ifdef __x86_64__
if (a1.IsEmpty()) {
XFASTCALL;
} else if (a2.IsEmpty()) {
XFASTCALL1;
} else {
XFASTCALL2;
}
if (a1.IsEmpty()) {
XFASTCALL;
} else if (a2.IsEmpty()) {
XFASTCALL1;
} else {
XFASTCALL2;
}
#else
if (a1.IsEmpty()) {
XFASTCALL;
} else if (a2.IsEmpty()) {
XFASTCALL1;
} else {
XFASTCALL2;
}
if (a1.IsEmpty()) {
XFASTCALL;
} else if (a2.IsEmpty()) {
XFASTCALL1;
} else {
XFASTCALL2;
}
#endif
}
}
template< typename T > __fi
void operator()( T* func, u32 a1, const xRegisterLong& a2) const
{
void* f = (void*)func;
template <typename T>
__fi void operator()(T *func, u32 a1, const xRegisterLong &a2) const
{
void *f = (void *)func;
#ifdef __x86_64__
XFASTCALL2;
XFASTCALL2;
#else
XFASTCALL2;
XFASTCALL2;
#endif
}
}
template< typename T > __fi
void operator()( T* func, const xIndirectVoid& a1) const
{
void* f = (void*)func;
template <typename T>
__fi void operator()(T *func, const xIndirectVoid &a1) const
{
void *f = (void *)func;
#ifdef __x86_64__
XFASTCALL1;
XFASTCALL1;
#else
XFASTCALL1;
XFASTCALL1;
#endif
}
}
template< typename T > __fi
void operator()( T* func, u32 a1, u32 a2) const
{
void* f = (void*)func;
template <typename T>
__fi void operator()(T *func, u32 a1, u32 a2) const
{
void *f = (void *)func;
#ifdef __x86_64__
XFASTCALL2;
XFASTCALL2;
#else
XFASTCALL2;
XFASTCALL2;
#endif
}
}
template< typename T > __fi
void operator()( T* func, u32 a1) const
{
void* f = (void*)func;
template <typename T>
__fi void operator()(T *func, u32 a1) const
{
void *f = (void *)func;
#ifdef __x86_64__
XFASTCALL1;
XFASTCALL1;
#else
XFASTCALL1;
XFASTCALL1;
#endif
}
}
void operator()(const xIndirect32& f, const xRegisterLong& a1 = xEmptyReg, const xRegisterLong& a2 = xEmptyReg) const
{
void operator()(const xIndirect32 &f, const xRegisterLong &a1 = xEmptyReg, const xRegisterLong &a2 = xEmptyReg) const
{
#ifdef __x86_64__
if (a1.IsEmpty()) {
XFASTCALL;
} else if (a2.IsEmpty()) {
XFASTCALL1;
} else {
XFASTCALL2;
}
if (a1.IsEmpty()) {
XFASTCALL;
} else if (a2.IsEmpty()) {
XFASTCALL1;
} else {
XFASTCALL2;
}
#else
if (a1.IsEmpty()) {
XFASTCALL;
} else if (a2.IsEmpty()) {
XFASTCALL1;
} else {
XFASTCALL2;
}
if (a1.IsEmpty()) {
XFASTCALL;
} else if (a2.IsEmpty()) {
XFASTCALL1;
} else {
XFASTCALL2;
}
#endif
}
}
#undef XFASTCALL
#undef XFASTCALL1
#undef XFASTCALL2
};
} // End namespace x86Emitter
} // End namespace x86Emitter

View File

@ -18,7 +18,8 @@
// Header: ix86_impl_movs.h -- covers mov, cmov, movsx/movzx, and SETcc (which shares
// with cmov many similarities).
namespace x86Emitter {
namespace x86Emitter
{
// --------------------------------------------------------------------------------------
// MovImplAll
@ -27,13 +28,13 @@ namespace x86Emitter {
//
struct xImpl_Mov
{
xImpl_Mov() {} // Satisfy GCC's whims.
xImpl_Mov() {} // Satisfy GCC's whims.
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const;
void operator()( const xIndirectVoid& dest, const xRegisterInt& from ) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& src ) const;
void operator()( const xIndirect64orLess& dest, int imm ) const;
void operator()( const xRegisterInt& to, int imm, bool preserve_flags=false ) const;
void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()(const xIndirectVoid &dest, const xRegisterInt &from) const;
void operator()(const xRegisterInt &to, const xIndirectVoid &src) const;
void operator()(const xIndirect64orLess &dest, int imm) const;
void operator()(const xRegisterInt &to, int imm, bool preserve_flags = false) const;
#if 0
template< typename T > __noinline void operator()( const ModSibBase& to, const xImmReg<T>& immOrReg ) const
@ -84,22 +85,22 @@ struct xImpl_Mov
struct xImpl_CMov
{
JccComparisonType ccType;
void operator()( const xRegister16or32or64& to, const xRegister16or32or64& from ) const;
void operator()( const xRegister16or32or64& to, const xIndirectVoid& sibsrc ) const;
JccComparisonType ccType;
void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from) const;
void operator()(const xRegister16or32or64 &to, const xIndirectVoid &sibsrc) const;
//void operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from );
//void operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const;
//void operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from );
//void operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const;
};
struct xImpl_Set
{
JccComparisonType ccType;
JccComparisonType ccType;
void operator()( const xRegister8& to ) const;
void operator()( const xIndirect8& dest ) const;
void operator()(const xRegister8 &to) const;
void operator()(const xIndirect8 &dest) const;
//void operator()( const xDirectOrIndirect8& dest ) const;
//void operator()( const xDirectOrIndirect8& dest ) const;
};
@ -110,16 +111,16 @@ struct xImpl_Set
//
struct xImpl_MovExtend
{
bool SignExtend;
bool SignExtend;
void operator()( const xRegister16or32or64& to, const xRegister8& from ) const;
void operator()( const xRegister16or32or64& to, const xIndirect8& sibsrc ) const;
void operator()( const xRegister32or64& to, const xRegister16& from ) const;
void operator()( const xRegister32or64& to, const xIndirect16& sibsrc ) const;
void operator()(const xRegister16or32or64 &to, const xRegister8 &from) const;
void operator()(const xRegister16or32or64 &to, const xIndirect8 &sibsrc) const;
void operator()(const xRegister32or64 &to, const xRegister16 &from) const;
void operator()(const xRegister32or64 &to, const xIndirect16 &sibsrc) const;
//void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const;
//void operator()( const xRegister16or32& to, const xDirectOrIndirect8& src ) const;
//void operator()( const xRegister16& to, const xDirectOrIndirect8& src ) const;
//void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const;
//void operator()( const xRegister16or32& to, const xDirectOrIndirect8& src ) const;
//void operator()( const xRegister16& to, const xDirectOrIndirect8& src ) const;
};
} // End namespace x86Emitter
} // End namespace x86Emitter

View File

@ -15,22 +15,23 @@
#pragma once
namespace x86Emitter {
namespace x86Emitter
{
// --------------------------------------------------------------------------------------
// _SimdShiftHelper
// --------------------------------------------------------------------------------------
struct _SimdShiftHelper
{
u8 Prefix;
u16 Opcode;
u16 OpcodeImm;
u8 Modcode;
u8 Prefix;
u16 Opcode;
u16 OpcodeImm;
u8 Modcode;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const;
void operator()( const xRegisterSSE& to, u8 imm8 ) const;
void operator()(const xRegisterSSE &to, u8 imm8) const;
};
// --------------------------------------------------------------------------------------
@ -41,70 +42,70 @@ struct _SimdShiftHelper
//
struct xImplSimd_ShiftWithoutQ
{
const _SimdShiftHelper W;
const _SimdShiftHelper D;
const _SimdShiftHelper W;
const _SimdShiftHelper D;
};
// Implements PSRL and PSLL
//
struct xImplSimd_Shift
{
const _SimdShiftHelper W;
const _SimdShiftHelper D;
const _SimdShiftHelper Q;
const _SimdShiftHelper W;
const _SimdShiftHelper D;
const _SimdShiftHelper Q;
void DQ( const xRegisterSSE& to, u8 imm8 ) const;
void DQ(const xRegisterSSE &to, u8 imm8) const;
};
//////////////////////////////////////////////////////////////////////////////////////////
//
struct xImplSimd_AddSub
{
const xImplSimd_DestRegEither B;
const xImplSimd_DestRegEither W;
const xImplSimd_DestRegEither D;
const xImplSimd_DestRegEither Q;
const xImplSimd_DestRegEither B;
const xImplSimd_DestRegEither W;
const xImplSimd_DestRegEither D;
const xImplSimd_DestRegEither Q;
// Add/Sub packed signed byte [8bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither SB;
// Add/Sub packed signed byte [8bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither SB;
// Add/Sub packed signed word [16bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither SW;
// Add/Sub packed signed word [16bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither SW;
// Add/Sub packed unsigned byte [8bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither USB;
// Add/Sub packed unsigned byte [8bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither USB;
// Add/Sub packed unsigned word [16bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither USW;
// Add/Sub packed unsigned word [16bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither USW;
};
//////////////////////////////////////////////////////////////////////////////////////////
//
struct xImplSimd_PMul
{
const xImplSimd_DestRegEither LW;
const xImplSimd_DestRegEither HW;
const xImplSimd_DestRegEither HUW;
const xImplSimd_DestRegEither UDQ;
const xImplSimd_DestRegEither LW;
const xImplSimd_DestRegEither HW;
const xImplSimd_DestRegEither HUW;
const xImplSimd_DestRegEither UDQ;
// [SSE-3] PMULHRSW multiplies vertically each signed 16-bit integer from dest with the
// corresponding signed 16-bit integer of source, producing intermediate signed 32-bit
// integers. Each intermediate 32-bit integer is truncated to the 18 most significant
// bits. Rounding is always performed by adding 1 to the least significant bit of the
// 18-bit intermediate result. The final result is obtained by selecting the 16 bits
// immediately to the right of the most significant bit of each 18-bit intermediate
// result and packed to the destination operand.
//
// Both operands can be MMX or XMM registers. Source can be register or memory.
//
const xImplSimd_DestRegEither HRSW;
// [SSE-3] PMULHRSW multiplies vertically each signed 16-bit integer from dest with the
// corresponding signed 16-bit integer of source, producing intermediate signed 32-bit
// integers. Each intermediate 32-bit integer is truncated to the 18 most significant
// bits. Rounding is always performed by adding 1 to the least significant bit of the
// 18-bit intermediate result. The final result is obtained by selecting the 16 bits
// immediately to the right of the most significant bit of each 18-bit intermediate
// result and packed to the destination operand.
//
// Both operands can be MMX or XMM registers. Source can be register or memory.
//
const xImplSimd_DestRegEither HRSW;
// [SSE-4.1] Multiply the packed dword signed integers in dest with src, and store
// the low 32 bits of each product in xmm1.
const xImplSimd_DestRegSSE LD;
// [SSE-4.1] Multiply the packed dword signed integers in dest with src, and store
// the low 32 bits of each product in xmm1.
const xImplSimd_DestRegSSE LD;
// [SSE-4.1] Multiply the packed signed dword integers in dest with src.
const xImplSimd_DestRegSSE DQ;
// [SSE-4.1] Multiply the packed signed dword integers in dest with src.
const xImplSimd_DestRegSSE DQ;
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -112,8 +113,8 @@ struct xImplSimd_PMul
//
struct xImplSimd_rSqrt
{
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE SS;
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -121,17 +122,17 @@ struct xImplSimd_rSqrt
//
struct xImplSimd_Sqrt
{
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD;
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD;
};
//////////////////////////////////////////////////////////////////////////////////////////
//
struct xImplSimd_AndNot
{
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD;
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -139,17 +140,17 @@ struct xImplSimd_AndNot
//
struct xImplSimd_PAbsolute
{
// [sSSE-3] Computes the absolute value of bytes in the src, and stores the result
// in dest, as UNSIGNED.
const xImplSimd_DestRegEither B;
// [sSSE-3] Computes the absolute value of bytes in the src, and stores the result
// in dest, as UNSIGNED.
const xImplSimd_DestRegEither B;
// [sSSE-3] Computes the absolute value of word in the src, and stores the result
// in dest, as UNSIGNED.
const xImplSimd_DestRegEither W;
// [sSSE-3] Computes the absolute value of word in the src, and stores the result
// in dest, as UNSIGNED.
const xImplSimd_DestRegEither W;
// [sSSE-3] Computes the absolute value of doublewords in the src, and stores the
// result in dest, as UNSIGNED.
const xImplSimd_DestRegEither D;
// [sSSE-3] Computes the absolute value of doublewords in the src, and stores the
// result in dest, as UNSIGNED.
const xImplSimd_DestRegEither D;
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -158,27 +159,26 @@ struct xImplSimd_PAbsolute
//
struct xImplSimd_PSign
{
// [sSSE-3] negates each byte element of dest if the signed integer value of the
// corresponding data element in src is less than zero. If the signed integer value
// of a data element in src is positive, the corresponding data element in dest is
// unchanged. If a data element in src is zero, the corresponding data element in
// dest is set to zero.
const xImplSimd_DestRegEither B;
// [sSSE-3] negates each byte element of dest if the signed integer value of the
// corresponding data element in src is less than zero. If the signed integer value
// of a data element in src is positive, the corresponding data element in dest is
// unchanged. If a data element in src is zero, the corresponding data element in
// dest is set to zero.
const xImplSimd_DestRegEither B;
// [sSSE-3] negates each word element of dest if the signed integer value of the
// corresponding data element in src is less than zero. If the signed integer value
// of a data element in src is positive, the corresponding data element in dest is
// unchanged. If a data element in src is zero, the corresponding data element in
// dest is set to zero.
const xImplSimd_DestRegEither W;
// [sSSE-3] negates each doubleword element of dest if the signed integer value
// of the corresponding data element in src is less than zero. If the signed integer
// value of a data element in src is positive, the corresponding data element in dest
// is unchanged. If a data element in src is zero, the corresponding data element in
// dest is set to zero.
const xImplSimd_DestRegEither D;
// [sSSE-3] negates each word element of dest if the signed integer value of the
// corresponding data element in src is less than zero. If the signed integer value
// of a data element in src is positive, the corresponding data element in dest is
// unchanged. If a data element in src is zero, the corresponding data element in
// dest is set to zero.
const xImplSimd_DestRegEither W;
// [sSSE-3] negates each doubleword element of dest if the signed integer value
// of the corresponding data element in src is less than zero. If the signed integer
// value of a data element in src is positive, the corresponding data element in dest
// is unchanged. If a data element in src is zero, the corresponding data element in
// dest is set to zero.
const xImplSimd_DestRegEither D;
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -186,31 +186,31 @@ struct xImplSimd_PSign
//
struct xImplSimd_PMultAdd
{
// Multiplies the individual signed words of dest by the corresponding signed words
// of src, producing temporary signed, doubleword results. The adjacent doubleword
// results are then summed and stored in the destination operand.
//
// DEST[31:0] = ( DEST[15:0] * SRC[15:0]) + (DEST[31:16] * SRC[31:16] );
// DEST[63:32] = ( DEST[47:32] * SRC[47:32]) + (DEST[63:48] * SRC[63:48] );
// [.. repeat in the case of XMM src/dest operands ..]
//
const xImplSimd_DestRegEither WD;
// Multiplies the individual signed words of dest by the corresponding signed words
// of src, producing temporary signed, doubleword results. The adjacent doubleword
// results are then summed and stored in the destination operand.
//
// DEST[31:0] = ( DEST[15:0] * SRC[15:0]) + (DEST[31:16] * SRC[31:16] );
// DEST[63:32] = ( DEST[47:32] * SRC[47:32]) + (DEST[63:48] * SRC[63:48] );
// [.. repeat in the case of XMM src/dest operands ..]
//
const xImplSimd_DestRegEither WD;
// [sSSE-3] multiplies vertically each unsigned byte of dest with the corresponding
// signed byte of src, producing intermediate signed 16-bit integers. Each adjacent
// pair of signed words is added and the saturated result is packed to dest.
// For example, the lowest-order bytes (bits 7-0) in src and dest are multiplied
// and the intermediate signed word result is added with the corresponding
// intermediate result from the 2nd lowest-order bytes (bits 15-8) of the operands;
// the sign-saturated result is stored in the lowest word of dest (bits 15-0).
// The same operation is performed on the other pairs of adjacent bytes.
//
// In Coder Speak:
// DEST[15-0] = SaturateToSignedWord( SRC[15-8] * DEST[15-8] + SRC[7-0] * DEST[7-0] );
// DEST[31-16] = SaturateToSignedWord( SRC[31-24] * DEST[31-24] + SRC[23-16] * DEST[23-16] );
// [.. repeat for each 16 bits up to 64 (mmx) or 128 (xmm) ..]
//
const xImplSimd_DestRegEither UBSW;
// [sSSE-3] multiplies vertically each unsigned byte of dest with the corresponding
// signed byte of src, producing intermediate signed 16-bit integers. Each adjacent
// pair of signed words is added and the saturated result is packed to dest.
// For example, the lowest-order bytes (bits 7-0) in src and dest are multiplied
// and the intermediate signed word result is added with the corresponding
// intermediate result from the 2nd lowest-order bytes (bits 15-8) of the operands;
// the sign-saturated result is stored in the lowest word of dest (bits 15-0).
// The same operation is performed on the other pairs of adjacent bytes.
//
// In Coder Speak:
// DEST[15-0] = SaturateToSignedWord( SRC[15-8] * DEST[15-8] + SRC[7-0] * DEST[7-0] );
// DEST[31-16] = SaturateToSignedWord( SRC[31-24] * DEST[31-24] + SRC[23-16] * DEST[23-16] );
// [.. repeat for each 16 bits up to 64 (mmx) or 128 (xmm) ..]
//
const xImplSimd_DestRegEither UBSW;
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -218,21 +218,21 @@ struct xImplSimd_PMultAdd
//
struct xImplSimd_HorizAdd
{
// [SSE-3] Horizontal Add of Packed Data. A three step process:
// * Adds the single-precision floating-point values in the first and second dwords of
// dest and stores the result in the first dword of dest.
// * Adds single-precision floating-point values in the third and fourth dword of dest
// stores the result in the second dword of dest.
// * Adds single-precision floating-point values in the first and second dword of *src*
// and stores the result in the third dword of dest.
const xImplSimd_DestRegSSE PS;
// [SSE-3] Horizontal Add of Packed Data. A three step process:
// * Adds the single-precision floating-point values in the first and second dwords of
// dest and stores the result in the first dword of dest.
// * Adds single-precision floating-point values in the third and fourth dword of dest
// stores the result in the second dword of dest.
// * Adds single-precision floating-point values in the first and second dword of *src*
// and stores the result in the third dword of dest.
const xImplSimd_DestRegSSE PS;
// [SSE-3] Horizontal Add of Packed Data. A two step process:
// * Adds the double-precision floating-point values in the high and low quadwords of
// dest and stores the result in the low quadword of dest.
// * Adds the double-precision floating-point values in the high and low quadwords of
// *src* stores the result in the high quadword of dest.
const xImplSimd_DestRegSSE PD;
// [SSE-3] Horizontal Add of Packed Data. A two step process:
// * Adds the double-precision floating-point values in the high and low quadwords of
// dest and stores the result in the low quadword of dest.
// * Adds the double-precision floating-point values in the high and low quadwords of
// *src* stores the result in the high quadword of dest.
const xImplSimd_DestRegSSE PD;
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -240,23 +240,23 @@ struct xImplSimd_HorizAdd
//
struct xImplSimd_DotProduct
{
// [SSE-4.1] Conditionally multiplies the packed single precision floating-point
// values in dest with the packed single-precision floats in src depending on a
// mask extracted from the high 4 bits of the immediate byte. If a condition mask
// bit in Imm8[7:4] is zero, the corresponding multiplication is replaced by a value
// of 0.0. The four resulting single-precision values are summed into an inter-
// mediate result.
//
// The intermediate result is conditionally broadcasted to the destination using a
// broadcast mask specified by bits [3:0] of the immediate byte. If a broadcast
// mask bit is 1, the intermediate result is copied to the corresponding dword
// element in dest. If a broadcast mask bit is zero, the corresponding element in
// the destination is set to zero.
//
xImplSimd_DestRegImmSSE PS;
// [SSE-4.1] Conditionally multiplies the packed single precision floating-point
// values in dest with the packed single-precision floats in src depending on a
// mask extracted from the high 4 bits of the immediate byte. If a condition mask
// bit in Imm8[7:4] is zero, the corresponding multiplication is replaced by a value
// of 0.0. The four resulting single-precision values are summed into an inter-
// mediate result.
//
// The intermediate result is conditionally broadcasted to the destination using a
// broadcast mask specified by bits [3:0] of the immediate byte. If a broadcast
// mask bit is 1, the intermediate result is copied to the corresponding dword
// element in dest. If a broadcast mask bit is zero, the corresponding element in
// the destination is set to zero.
//
xImplSimd_DestRegImmSSE PS;
// [SSE-4.1]
xImplSimd_DestRegImmSSE PD;
// [SSE-4.1]
xImplSimd_DestRegImmSSE PD;
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -264,54 +264,53 @@ struct xImplSimd_DotProduct
// (SSE4.1 only!)
struct xImplSimd_Round
{
// [SSE-4.1] Rounds the 4 packed single-precision src values and stores them in dest.
//
// Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only.
//
// Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
//
const xImplSimd_DestRegImmSSE PS;
// [SSE-4.1] Rounds the 4 packed single-precision src values and stores them in dest.
//
// Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only.
//
// Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
//
const xImplSimd_DestRegImmSSE PS;
// [SSE-4.1] Rounds the 2 packed double-precision src values and stores them in dest.
//
// Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only.
//
// Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
//
const xImplSimd_DestRegImmSSE PD;
// [SSE-4.1] Rounds the 2 packed double-precision src values and stores them in dest.
//
// Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only.
//
// Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
//
const xImplSimd_DestRegImmSSE PD;
// [SSE-4.1] Rounds the single-precision src value and stores in dest.
//
// Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only.
//
// Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
//
const xImplSimd_DestRegImmSSE SS;
// [SSE-4.1] Rounds the single-precision src value and stores in dest.
//
// Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only.
//
// Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
//
const xImplSimd_DestRegImmSSE SS;
// [SSE-4.1] Rounds the double-precision src value and stores in dest.
//
// Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only.
//
// Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
//
const xImplSimd_DestRegImmSSE SD;
// [SSE-4.1] Rounds the double-precision src value and stores in dest.
//
// Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only.
//
// Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
//
const xImplSimd_DestRegImmSSE SD;
};
} // End namespace x86Emitter
} // End namespace x86Emitter

View File

@ -15,33 +15,34 @@
#pragma once
namespace x86Emitter {
namespace x86Emitter
{
struct xImplSimd_MinMax
{
const xImplSimd_DestRegSSE PS; // packed single precision
const xImplSimd_DestRegSSE PD; // packed double precision
const xImplSimd_DestRegSSE SS; // scalar single precision
const xImplSimd_DestRegSSE SD; // scalar double precision
const xImplSimd_DestRegSSE PS; // packed single precision
const xImplSimd_DestRegSSE PD; // packed double precision
const xImplSimd_DestRegSSE SS; // scalar single precision
const xImplSimd_DestRegSSE SD; // scalar double precision
};
//////////////////////////////////////////////////////////////////////////////////////////
//
struct xImplSimd_Compare
{
SSE2_ComparisonType CType;
SSE2_ComparisonType CType;
void PS( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void PS( const xRegisterSSE& to, const xIndirectVoid& from ) const;
void PS(const xRegisterSSE &to, const xRegisterSSE &from) const;
void PS(const xRegisterSSE &to, const xIndirectVoid &from) const;
void PD( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void PD( const xRegisterSSE& to, const xIndirectVoid& from ) const;
void PD(const xRegisterSSE &to, const xRegisterSSE &from) const;
void PD(const xRegisterSSE &to, const xIndirectVoid &from) const;
void SS( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void SS( const xRegisterSSE& to, const xIndirectVoid& from ) const;
void SS(const xRegisterSSE &to, const xRegisterSSE &from) const;
void SS(const xRegisterSSE &to, const xIndirectVoid &from) const;
void SD( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void SD( const xRegisterSSE& to, const xIndirectVoid& from ) const;
void SD(const xRegisterSSE &to, const xRegisterSSE &from) const;
void SD(const xRegisterSSE &to, const xIndirectVoid &from) const;
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -49,8 +50,8 @@ struct xImplSimd_Compare
//
struct xImplSimd_COMI
{
const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD;
const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD;
};
@ -59,65 +60,64 @@ struct xImplSimd_COMI
struct xImplSimd_PCompare
{
public:
// Compare packed bytes for equality.
// If a data element in dest is equal to the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither EQB;
// Compare packed bytes for equality.
// If a data element in dest is equal to the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither EQB;
// Compare packed words for equality.
// If a data element in dest is equal to the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither EQW;
// Compare packed words for equality.
// If a data element in dest is equal to the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither EQW;
// Compare packed doublewords [32-bits] for equality.
// If a data element in dest is equal to the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither EQD;
// Compare packed doublewords [32-bits] for equality.
// If a data element in dest is equal to the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither EQD;
// Compare packed signed bytes for greater than.
// If a data element in dest is greater than the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither GTB;
// Compare packed signed bytes for greater than.
// If a data element in dest is greater than the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither GTB;
// Compare packed signed words for greater than.
// If a data element in dest is greater than the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither GTW;
// Compare packed signed words for greater than.
// If a data element in dest is greater than the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither GTW;
// Compare packed signed doublewords [32-bits] for greater than.
// If a data element in dest is greater than the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither GTD;
// Compare packed signed doublewords [32-bits] for greater than.
// If a data element in dest is greater than the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither GTD;
};
//////////////////////////////////////////////////////////////////////////////////////////
//
struct xImplSimd_PMinMax
{
// Compare packed unsigned byte integers in dest to src and store packed min/max
// values in dest.
const xImplSimd_DestRegEither UB;
// Compare packed unsigned byte integers in dest to src and store packed min/max
// values in dest.
const xImplSimd_DestRegEither UB;
// Compare packed signed word integers in dest to src and store packed min/max
// values in dest.
const xImplSimd_DestRegEither SW;
// Compare packed signed word integers in dest to src and store packed min/max
// values in dest.
const xImplSimd_DestRegEither SW;
// [SSE-4.1] Compare packed signed byte integers in dest to src and store
// packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE SB;
// [SSE-4.1] Compare packed signed byte integers in dest to src and store
// packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE SB;
// [SSE-4.1] Compare packed signed doubleword integers in dest to src and store
// packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE SD;
// [SSE-4.1] Compare packed signed doubleword integers in dest to src and store
// packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE SD;
// [SSE-4.1] Compare packed unsigned word integers in dest to src and store
// packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE UW;
// [SSE-4.1] Compare packed unsigned word integers in dest to src and store
// packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE UW;
// [SSE-4.1] Compare packed unsigned doubleword integers in dest to src and store
// packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE UD;
// [SSE-4.1] Compare packed unsigned doubleword integers in dest to src and store
// packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE UD;
};
} // end namespace x86Emitter
} // end namespace x86Emitter

View File

@ -15,7 +15,8 @@
#pragma once
namespace x86Emitter {
namespace x86Emitter
{
// =====================================================================================================
// xImpl_SIMD Types (template free!)
@ -27,11 +28,11 @@ namespace x86Emitter {
//
struct xImplSimd_DestRegSSE
{
u8 Prefix;
u16 Opcode;
u8 Prefix;
u16 Opcode;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const;
};
// ------------------------------------------------------------------------
@ -40,20 +41,20 @@ struct xImplSimd_DestRegSSE
//
struct xImplSimd_DestRegImmSSE
{
u8 Prefix;
u16 Opcode;
u8 Prefix;
u16 Opcode;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm ) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm ) const;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm) const;
};
struct xImplSimd_DestSSE_CmpImm
{
u8 Prefix;
u16 Opcode;
u8 Prefix;
u16 Opcode;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from, SSE2_ComparisonType imm ) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from, SSE2_ComparisonType imm ) const;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from, SSE2_ComparisonType imm) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from, SSE2_ComparisonType imm) const;
};
// ------------------------------------------------------------------------
@ -62,12 +63,11 @@ struct xImplSimd_DestSSE_CmpImm
//
struct xImplSimd_DestRegEither
{
u8 Prefix;
u16 Opcode;
u8 Prefix;
u16 Opcode;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const;
};
} // end namespace x86Emitter
} // end namespace x86Emitter

View File

@ -15,7 +15,8 @@
#pragma once
namespace x86Emitter {
namespace x86Emitter
{
// --------------------------------------------------------------------------------------
// xImplSimd_MovHL
@ -25,13 +26,13 @@ namespace x86Emitter {
//
struct xImplSimd_MovHL
{
u16 Opcode;
u16 Opcode;
void PS( const xRegisterSSE& to, const xIndirectVoid& from ) const;
void PS( const xIndirectVoid& to, const xRegisterSSE& from ) const;
void PS(const xRegisterSSE &to, const xIndirectVoid &from) const;
void PS(const xIndirectVoid &to, const xRegisterSSE &from) const;
void PD( const xRegisterSSE& to, const xIndirectVoid& from ) const;
void PD( const xIndirectVoid& to, const xRegisterSSE& from ) const;
void PD(const xRegisterSSE &to, const xIndirectVoid &from) const;
void PD(const xIndirectVoid &to, const xRegisterSSE &from) const;
};
// --------------------------------------------------------------------------------------
@ -42,10 +43,10 @@ struct xImplSimd_MovHL
//
struct xImplSimd_MovHL_RtoR
{
u16 Opcode;
u16 Opcode;
void PS( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void PD( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void PS(const xRegisterSSE &to, const xRegisterSSE &from) const;
void PD(const xRegisterSSE &to, const xRegisterSSE &from) const;
};
// --------------------------------------------------------------------------------------
@ -59,12 +60,12 @@ struct xImplSimd_MovHL_RtoR
//
struct xImplSimd_MoveSSE
{
u8 Prefix;
bool isAligned;
u8 Prefix;
bool isAligned;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
void operator()( const xIndirectVoid& to, const xRegisterSSE& from ) const;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const;
void operator()(const xIndirectVoid &to, const xRegisterSSE &from) const;
};
// --------------------------------------------------------------------------------------
@ -78,12 +79,12 @@ struct xImplSimd_MoveSSE
struct xImplSimd_MoveDQ
{
u8 Prefix;
bool isAligned;
u8 Prefix;
bool isAligned;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
void operator()( const xIndirectVoid& to, const xRegisterSSE& from ) const;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const;
void operator()(const xIndirectVoid &to, const xRegisterSSE &from) const;
};
// --------------------------------------------------------------------------------------
@ -93,41 +94,41 @@ struct xImplSimd_MoveDQ
//
struct xImplSimd_Blend
{
// [SSE-4.1] Conditionally copies dword values from src to dest, depending on the
// mask bits in the immediate operand (bits [3:0]). Each mask bit corresponds to a
// dword element in a 128-bit operand.
//
// If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged.
//
xImplSimd_DestRegImmSSE PS;
// [SSE-4.1] Conditionally copies dword values from src to dest, depending on the
// mask bits in the immediate operand (bits [3:0]). Each mask bit corresponds to a
// dword element in a 128-bit operand.
//
// If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged.
//
xImplSimd_DestRegImmSSE PS;
// [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the
// mask bits in the immediate operand (bits [1:0]). Each mask bit corresponds to a
// quadword element in a 128-bit operand.
//
// If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged.
//
xImplSimd_DestRegImmSSE PD;
// [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the
// mask bits in the immediate operand (bits [1:0]). Each mask bit corresponds to a
// quadword element in a 128-bit operand.
//
// If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged.
//
xImplSimd_DestRegImmSSE PD;
// [SSE-4.1] Conditionally copies dword values from src to dest, depending on the
// mask (bits [3:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds
// to a dword element in the 128-bit operand.
//
// If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged.
//
xImplSimd_DestRegSSE VPS;
// [SSE-4.1] Conditionally copies dword values from src to dest, depending on the
// mask (bits [3:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds
// to a dword element in the 128-bit operand.
//
// If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged.
//
xImplSimd_DestRegSSE VPS;
// [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the
// mask (bits [1:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds
// to a quadword element in the 128-bit operand.
//
// If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged.
//
xImplSimd_DestRegSSE VPD;
// [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the
// mask (bits [1:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds
// to a quadword element in the 128-bit operand.
//
// If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged.
//
xImplSimd_DestRegSSE VPD;
};
// --------------------------------------------------------------------------------------
@ -137,38 +138,36 @@ struct xImplSimd_Blend
//
struct xImplSimd_PMove
{
u16 OpcodeBase;
u16 OpcodeBase;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into word integers
// and store them in dest.
void BW( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void BW( const xRegisterSSE& to, const xIndirect64& from ) const;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into word integers
// and store them in dest.
void BW(const xRegisterSSE &to, const xRegisterSSE &from) const;
void BW(const xRegisterSSE &to, const xIndirect64 &from) const;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into dword integers
// and store them in dest.
void BD( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void BD( const xRegisterSSE& to, const xIndirect32& from ) const;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into dword integers
// and store them in dest.
void BD(const xRegisterSSE &to, const xRegisterSSE &from) const;
void BD(const xRegisterSSE &to, const xIndirect32 &from) const;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into qword integers
// and store them in dest.
void BQ( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void BQ( const xRegisterSSE& to, const xIndirect16& from ) const;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into qword integers
// and store them in dest.
void BQ(const xRegisterSSE &to, const xRegisterSSE &from) const;
void BQ(const xRegisterSSE &to, const xIndirect16 &from) const;
// [SSE-4.1] Zero/Sign-extend the low word values in src into dword integers
// and store them in dest.
void WD( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void WD( const xRegisterSSE& to, const xIndirect64& from ) const;
// [SSE-4.1] Zero/Sign-extend the low word values in src into dword integers
// and store them in dest.
void WD(const xRegisterSSE &to, const xRegisterSSE &from) const;
void WD(const xRegisterSSE &to, const xIndirect64 &from) const;
// [SSE-4.1] Zero/Sign-extend the low word values in src into qword integers
// and store them in dest.
void WQ( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void WQ( const xRegisterSSE& to, const xIndirect32& from ) const;
// [SSE-4.1] Zero/Sign-extend the low word values in src into qword integers
// and store them in dest.
void WQ(const xRegisterSSE &to, const xRegisterSSE &from) const;
void WQ(const xRegisterSSE &to, const xIndirect32 &from) const;
// [SSE-4.1] Zero/Sign-extend the low dword values in src into qword integers
// and store them in dest.
void DQ( const xRegisterSSE& to, const xRegisterSSE& from ) const;
void DQ( const xRegisterSSE& to, const xIndirect64& from ) const;
// [SSE-4.1] Zero/Sign-extend the low dword values in src into qword integers
// and store them in dest.
void DQ(const xRegisterSSE &to, const xRegisterSSE &from) const;
void DQ(const xRegisterSSE &to, const xIndirect64 &from) const;
};
}

View File

@ -15,20 +15,21 @@
#pragma once
namespace x86Emitter {
namespace x86Emitter
{
// --------------------------------------------------------------------------------------
// xImplSimd_Shuffle
// --------------------------------------------------------------------------------------
struct xImplSimd_Shuffle
{
inline void _selector_assertion_check( u8 selector ) const;
inline void _selector_assertion_check(u8 selector) const;
void PS( const xRegisterSSE& to, const xRegisterSSE& from, u8 selector ) const;
void PS( const xRegisterSSE& to, const xIndirectVoid& from, u8 selector ) const;
void PS(const xRegisterSSE &to, const xRegisterSSE &from, u8 selector) const;
void PS(const xRegisterSSE &to, const xIndirectVoid &from, u8 selector) const;
void PD( const xRegisterSSE& to, const xRegisterSSE& from, u8 selector ) const;
void PD( const xRegisterSSE& to, const xIndirectVoid& from, u8 selector ) const;
void PD(const xRegisterSSE &to, const xRegisterSSE &from, u8 selector) const;
void PD(const xRegisterSSE &to, const xIndirectVoid &from, u8 selector) const;
};
// --------------------------------------------------------------------------------------
@ -36,33 +37,33 @@ struct xImplSimd_Shuffle
// --------------------------------------------------------------------------------------
struct xImplSimd_PShuffle
{
// Copies doublewords from src and inserts them into dest at dword locations selected
// with the order operand (8 bit immediate).
const xImplSimd_DestRegImmSSE D;
// Copies doublewords from src and inserts them into dest at dword locations selected
// with the order operand (8 bit immediate).
const xImplSimd_DestRegImmSSE D;
// Copies words from the low quadword of src and inserts them into the low quadword
// of dest at word locations selected with the order operand (8 bit immediate).
// The high quadword of src is copied to the high quadword of dest.
const xImplSimd_DestRegImmSSE LW;
// Copies words from the low quadword of src and inserts them into the low quadword
// of dest at word locations selected with the order operand (8 bit immediate).
// The high quadword of src is copied to the high quadword of dest.
const xImplSimd_DestRegImmSSE LW;
// Copies words from the high quadword of src and inserts them into the high quadword
// of dest at word locations selected with the order operand (8 bit immediate).
// The low quadword of src is copied to the low quadword of dest.
const xImplSimd_DestRegImmSSE HW;
// Copies words from the high quadword of src and inserts them into the high quadword
// of dest at word locations selected with the order operand (8 bit immediate).
// The low quadword of src is copied to the low quadword of dest.
const xImplSimd_DestRegImmSSE HW;
// [sSSE-3] Performs in-place shuffles of bytes in dest according to the shuffle
// control mask in src. If the most significant bit (bit[7]) of each byte of the
// shuffle control mask is set, then constant zero is written in the result byte.
// Each byte in the shuffle control mask forms an index to permute the corresponding
// byte in dest. The value of each index is the least significant 4 bits (128-bit
// operation) or 3 bits (64-bit operation) of the shuffle control byte.
//
const xImplSimd_DestRegEither B;
// [sSSE-3] Performs in-place shuffles of bytes in dest according to the shuffle
// control mask in src. If the most significant bit (bit[7]) of each byte of the
// shuffle control mask is set, then constant zero is written in the result byte.
// Each byte in the shuffle control mask forms an index to permute the corresponding
// byte in dest. The value of each index is the least significant 4 bits (128-bit
// operation) or 3 bits (64-bit operation) of the shuffle control byte.
//
const xImplSimd_DestRegEither B;
// below is my test bed for a new system, free of subclasses. Was supposed to improve intellisense
// but it doesn't (makes it worse). Will try again in MSVC 2010. --air
// below is my test bed for a new system, free of subclasses. Was supposed to improve intellisense
// but it doesn't (makes it worse). Will try again in MSVC 2010. --air
#if 0
#if 0
// Copies words from src and inserts them into dest at word locations selected with
// the order operand (8 bit immediate).
@ -92,7 +93,7 @@ struct xImplSimd_PShuffle
//
void B( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
void B( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
#endif
#endif
};
// --------------------------------------------------------------------------------------
@ -100,23 +101,23 @@ struct xImplSimd_PShuffle
// --------------------------------------------------------------------------------------
struct SimdImpl_PUnpack
{
// Unpack and interleave low-order bytes from src and dest into dest.
const xImplSimd_DestRegEither LBW;
// Unpack and interleave low-order words from src and dest into dest.
const xImplSimd_DestRegEither LWD;
// Unpack and interleave low-order doublewords from src and dest into dest.
const xImplSimd_DestRegEither LDQ;
// Unpack and interleave low-order quadwords from src and dest into dest.
const xImplSimd_DestRegSSE LQDQ;
// Unpack and interleave low-order bytes from src and dest into dest.
const xImplSimd_DestRegEither LBW;
// Unpack and interleave low-order words from src and dest into dest.
const xImplSimd_DestRegEither LWD;
// Unpack and interleave low-order doublewords from src and dest into dest.
const xImplSimd_DestRegEither LDQ;
// Unpack and interleave low-order quadwords from src and dest into dest.
const xImplSimd_DestRegSSE LQDQ;
// Unpack and interleave high-order bytes from src and dest into dest.
const xImplSimd_DestRegEither HBW;
// Unpack and interleave high-order words from src and dest into dest.
const xImplSimd_DestRegEither HWD;
// Unpack and interleave high-order doublewords from src and dest into dest.
const xImplSimd_DestRegEither HDQ;
// Unpack and interleave high-order quadwords from src and dest into dest.
const xImplSimd_DestRegSSE HQDQ;
// Unpack and interleave high-order bytes from src and dest into dest.
const xImplSimd_DestRegEither HBW;
// Unpack and interleave high-order words from src and dest into dest.
const xImplSimd_DestRegEither HWD;
// Unpack and interleave high-order doublewords from src and dest into dest.
const xImplSimd_DestRegEither HDQ;
// Unpack and interleave high-order quadwords from src and dest into dest.
const xImplSimd_DestRegSSE HQDQ;
};
// --------------------------------------------------------------------------------------
@ -126,21 +127,21 @@ struct SimdImpl_PUnpack
//
struct SimdImpl_Pack
{
// Converts packed signed word integers from src and dest into packed signed
// byte integers in dest, using signed saturation.
const xImplSimd_DestRegEither SSWB;
// Converts packed signed word integers from src and dest into packed signed
// byte integers in dest, using signed saturation.
const xImplSimd_DestRegEither SSWB;
// Converts packed signed dword integers from src and dest into packed signed
// word integers in dest, using signed saturation.
const xImplSimd_DestRegEither SSDW;
// Converts packed signed dword integers from src and dest into packed signed
// word integers in dest, using signed saturation.
const xImplSimd_DestRegEither SSDW;
// Converts packed unsigned word integers from src and dest into packed unsigned
// byte integers in dest, using unsigned saturation.
const xImplSimd_DestRegEither USWB;
// Converts packed unsigned word integers from src and dest into packed unsigned
// byte integers in dest, using unsigned saturation.
const xImplSimd_DestRegEither USWB;
// [SSE-4.1] Converts packed unsigned dword integers from src and dest into packed
// unsigned word integers in dest, using signed saturation.
const xImplSimd_DestRegSSE USDW;
// [SSE-4.1] Converts packed unsigned dword integers from src and dest into packed
// unsigned word integers in dest, using signed saturation.
const xImplSimd_DestRegSSE USDW;
};
// --------------------------------------------------------------------------------------
@ -148,50 +149,50 @@ struct SimdImpl_Pack
// --------------------------------------------------------------------------------------
struct xImplSimd_Unpack
{
// Unpacks the high doubleword [single-precision] values from src and dest into
// dest, such that the result of dest looks like this:
// dest[0] <- dest[2]
// dest[1] <- src[2]
// dest[2] <- dest[3]
// dest[3] <- src[3]
//
const xImplSimd_DestRegSSE HPS;
// Unpacks the high doubleword [single-precision] values from src and dest into
// dest, such that the result of dest looks like this:
// dest[0] <- dest[2]
// dest[1] <- src[2]
// dest[2] <- dest[3]
// dest[3] <- src[3]
//
const xImplSimd_DestRegSSE HPS;
// Unpacks the high quadword [double-precision] values from src and dest into
// dest, such that the result of dest looks like this:
// dest.lo <- dest.hi
// dest.hi <- src.hi
//
const xImplSimd_DestRegSSE HPD;
// Unpacks the high quadword [double-precision] values from src and dest into
// dest, such that the result of dest looks like this:
// dest.lo <- dest.hi
// dest.hi <- src.hi
//
const xImplSimd_DestRegSSE HPD;
// Unpacks the low doubleword [single-precision] values from src and dest into
// dest, such that the result of dest looks like this:
// dest[3] <- src[1]
// dest[2] <- dest[1]
// dest[1] <- src[0]
// dest[0] <- dest[0]
//
const xImplSimd_DestRegSSE LPS;
// Unpacks the low doubleword [single-precision] values from src and dest into
// dest, such that the result of dest looks like this:
// dest[3] <- src[1]
// dest[2] <- dest[1]
// dest[1] <- src[0]
// dest[0] <- dest[0]
//
const xImplSimd_DestRegSSE LPS;
// Unpacks the low quadword [double-precision] values from src and dest into
// dest, effectively moving the low portion of src into the upper portion of dest.
// The result of dest is loaded as such:
// dest.hi <- src.lo
// dest.lo <- dest.lo [remains unchanged!]
//
const xImplSimd_DestRegSSE LPD;
// Unpacks the low quadword [double-precision] values from src and dest into
// dest, effectively moving the low portion of src into the upper portion of dest.
// The result of dest is loaded as such:
// dest.hi <- src.lo
// dest.lo <- dest.lo [remains unchanged!]
//
const xImplSimd_DestRegSSE LPD;
};
struct xImplSimd_InsertExtractHelper
{
u16 Opcode;
u16 Opcode;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
void operator()( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
void operator()(const xRegisterSSE &to, const xRegister32 &from, u8 imm8) const;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
void operator()( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
void operator()(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm8) const;
};
// --------------------------------------------------------------------------------------
@ -201,14 +202,14 @@ struct xImplSimd_InsertExtractHelper
//
struct xImplSimd_PInsert
{
void W( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const;
void W( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const;
void W(const xRegisterSSE &to, const xRegister32 &from, u8 imm8) const;
void W(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm8) const;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
xImplSimd_InsertExtractHelper B;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
xImplSimd_InsertExtractHelper B;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
xImplSimd_InsertExtractHelper D;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
xImplSimd_InsertExtractHelper D;
};
@ -219,23 +220,22 @@ struct xImplSimd_PInsert
//
struct SimdImpl_PExtract
{
// Copies the word element specified by imm8 from src to dest. The upper bits
// of dest are zero-extended (cleared). This can be used to extract any single packed
// word value from src into an x86 32 bit register.
//
// [SSE-4.1] Note: Indirect memory forms of this instruction are an SSE-4.1 extension!
//
void W( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) const;
void W( const xIndirectVoid& dest, const xRegisterSSE& from, u8 imm8 ) const;
// Copies the word element specified by imm8 from src to dest. The upper bits
// of dest are zero-extended (cleared). This can be used to extract any single packed
// word value from src into an x86 32 bit register.
//
// [SSE-4.1] Note: Indirect memory forms of this instruction are an SSE-4.1 extension!
//
void W(const xRegister32 &to, const xRegisterSSE &from, u8 imm8) const;
void W(const xIndirectVoid &dest, const xRegisterSSE &from, u8 imm8) const;
// [SSE-4.1] Copies the byte element specified by imm8 from src to dest. The upper bits
// of dest are zero-extended (cleared). This can be used to extract any single packed
// byte value from src into an x86 32 bit register.
const xImplSimd_InsertExtractHelper B;
// [SSE-4.1] Copies the byte element specified by imm8 from src to dest. The upper bits
// of dest are zero-extended (cleared). This can be used to extract any single packed
// byte value from src into an x86 32 bit register.
const xImplSimd_InsertExtractHelper B;
// [SSE-4.1] Copies the dword element specified by imm8 from src to dest. This can be
// used to extract any single packed dword value from src into an x86 32 bit register.
const xImplSimd_InsertExtractHelper D;
// [SSE-4.1] Copies the dword element specified by imm8 from src to dest. This can be
// used to extract any single packed dword value from src into an x86 32 bit register.
const xImplSimd_InsertExtractHelper D;
};
}

View File

@ -22,17 +22,17 @@
// For implementing SSE-only logic operations that have xmmreg,xmmreg/rm forms only,
// like ANDPS/ANDPD
//
template< u8 Prefix, u16 Opcode >
template <u8 Prefix, u16 Opcode>
class SimdImpl_DestRegSSE
{
public:
__forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const
{
bool isReallyAligned = ((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty();
pxAssertDev( isReallyAligned, "Alignment check failed on SSE indirect load." );
xOpWrite0F( Prefix, Opcode, to, from );
}
__forceinline void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const { xOpWrite0F(Prefix, Opcode, to, from); }
__forceinline void operator()(const xRegisterSSE &to, const ModSibBase &from) const
{
bool isReallyAligned = ((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty();
pxAssertDev(isReallyAligned, "Alignment check failed on SSE indirect load.");
xOpWrite0F(Prefix, Opcode, to, from);
}
SimdImpl_DestRegSSE() {} //GCWho?
SimdImpl_DestRegSSE() {} //GCWho?
};

View File

@ -17,7 +17,8 @@
// Implementations found here: TEST + BTS/BT/BTC/BTR + BSF/BSR! (for lack of better location)
namespace x86Emitter {
namespace x86Emitter
{
// --------------------------------------------------------------------------------------
// xImpl_Test
@ -25,17 +26,16 @@ namespace x86Emitter {
//
struct xImpl_Test
{
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const;
void operator()( const xIndirect64orLess& dest, int imm ) const;
void operator()( const xRegisterInt& to, int imm ) const;
void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()(const xIndirect64orLess &dest, int imm) const;
void operator()(const xRegisterInt &to, int imm) const;
};
enum G8Type
{
G8Type_BT = 4,
G8Type_BTS,
G8Type_BTR,
G8Type_BTC,
enum G8Type {
G8Type_BT = 4,
G8Type_BTS,
G8Type_BTR,
G8Type_BTC,
};
// --------------------------------------------------------------------------------------
@ -45,11 +45,11 @@ enum G8Type
//
struct xImpl_BitScan
{
// 0xbc [fwd] / 0xbd [rev]
u16 Opcode;
// 0xbc [fwd] / 0xbd [rev]
u16 Opcode;
void operator()( const xRegister16or32or64& to, const xRegister16or32or64& from ) const;
void operator()( const xRegister16or32or64& to, const xIndirectVoid& sibsrc ) const;
void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from) const;
void operator()(const xRegister16or32or64 &to, const xIndirectVoid &sibsrc) const;
};
// --------------------------------------------------------------------------------------
@ -59,17 +59,16 @@ struct xImpl_BitScan
//
struct xImpl_Group8
{
G8Type InstType;
G8Type InstType;
void operator()( const xRegister16or32or64& bitbase, const xRegister16or32or64& bitoffset ) const;
void operator()( const xRegister16or32or64& bitbase, u8 bitoffset ) const;
void operator()(const xRegister16or32or64 &bitbase, const xRegister16or32or64 &bitoffset) const;
void operator()(const xRegister16or32or64 &bitbase, u8 bitoffset) const;
void operator()( const xIndirectVoid& bitbase, const xRegister16or32or64& bitoffset ) const;
void operator()(const xIndirectVoid &bitbase, const xRegister16or32or64 &bitoffset) const;
void operator()( const xIndirect64& bitbase, u8 bitoffset ) const;
void operator()( const xIndirect32& bitbase, u8 bitoffset ) const;
void operator()( const xIndirect16& bitbase, u8 bitoffset ) const;
void operator()(const xIndirect64 &bitbase, u8 bitoffset) const;
void operator()(const xIndirect32 &bitbase, u8 bitoffset) const;
void operator()(const xIndirect16 &bitbase, u8 bitoffset) const;
};
} // End namespace x86Emitter
} // End namespace x86Emitter

View File

@ -18,7 +18,8 @@
// This header file is intended to be the future home of xchg, cmpxchg, xadd, and
// other threading-related exchange instructions.
namespace x86Emitter {
namespace x86Emitter
{
} // End namespace x86Emitter
} // End namespace x86Emitter

View File

@ -32,472 +32,551 @@
namespace x86Emitter
{
extern void xStoreReg( const xRegisterSSE& src );
extern void xRestoreReg( const xRegisterSSE& dest );
extern void xStoreReg(const xRegisterSSE &src);
extern void xRestoreReg(const xRegisterSSE &dest);
// ------------------------------------------------------------------------
// Group 1 Instruction Class
// ------------------------------------------------------------------------
// Group 1 Instruction Class
extern const xImpl_Group1 xADC;
extern const xImpl_Group1 xSBB;
extern const xImpl_Group1 xADC;
extern const xImpl_Group1 xSBB;
extern const xImpl_G1Logic xAND;
extern const xImpl_G1Logic xOR;
extern const xImpl_G1Logic xXOR;
extern const xImpl_G1Logic xAND;
extern const xImpl_G1Logic xOR;
extern const xImpl_G1Logic xXOR;
extern const xImpl_G1Arith xADD;
extern const xImpl_G1Arith xSUB;
extern const xImpl_G1Compare xCMP;
extern const xImpl_G1Arith xADD;
extern const xImpl_G1Arith xSUB;
extern const xImpl_G1Compare xCMP;
// ------------------------------------------------------------------------
// Group 2 Instruction Class
//
// Optimization Note: For Imm forms, we ignore the instruction if the shift count is
// zero. This is a safe optimization since any zero-value shift does not affect any
// flags.
// ------------------------------------------------------------------------
// Group 2 Instruction Class
//
// Optimization Note: For Imm forms, we ignore the instruction if the shift count is
// zero. This is a safe optimization since any zero-value shift does not affect any
// flags.
extern const xImpl_Mov xMOV;
extern const xImpl_Test xTEST;
extern const xImpl_Mov xMOV;
extern const xImpl_Test xTEST;
extern const xImpl_Group2 xROL, xROR,
xRCL, xRCR,
xSHL, xSHR,
xSAR;
extern const xImpl_Group2 xROL, xROR,
xRCL, xRCR,
xSHL, xSHR,
xSAR;
// ------------------------------------------------------------------------
// Group 3 Instruction Class
// ------------------------------------------------------------------------
// Group 3 Instruction Class
extern const xImpl_Group3 xNOT, xNEG;
extern const xImpl_Group3 xUMUL, xUDIV;
extern const xImpl_iDiv xDIV;
extern const xImpl_iMul xMUL;
extern const xImpl_Group3 xNOT, xNEG;
extern const xImpl_Group3 xUMUL, xUDIV;
extern const xImpl_iDiv xDIV;
extern const xImpl_iMul xMUL;
extern const xImpl_IncDec xINC, xDEC;
extern const xImpl_IncDec xINC, xDEC;
extern const xImpl_MovExtend xMOVZX, xMOVSX;
extern const xImpl_MovExtend xMOVZX, xMOVSX;
extern const xImpl_DwordShift xSHLD, xSHRD;
extern const xImpl_DwordShift xSHLD, xSHRD;
extern const xImpl_Group8 xBT;
extern const xImpl_Group8 xBTR;
extern const xImpl_Group8 xBTS;
extern const xImpl_Group8 xBTC;
extern const xImpl_Group8 xBT;
extern const xImpl_Group8 xBTR;
extern const xImpl_Group8 xBTS;
extern const xImpl_Group8 xBTC;
extern const xImpl_BitScan xBSF, xBSR;
extern const xImpl_BitScan xBSF, xBSR;
extern const xImpl_JmpCall xJMP;
extern const xImpl_JmpCall xJMP;
#ifdef __x86_64__
// 32 bits Call won't be compatible in 64 bits (different ABI)
// Just a reminder to port the code
[[deprecated]] extern const xImpl_JmpCall xCALL;
// 32 bits Call won't be compatible in 64 bits (different ABI)
// Just a reminder to port the code
[[deprecated]] extern const xImpl_JmpCall xCALL;
#else
extern const xImpl_JmpCall xCALL;
extern const xImpl_JmpCall xCALL;
#endif
extern const xImpl_FastCall xFastCall;
// ------------------------------------------------------------------------
extern const xImpl_CMov
xCMOVA, xCMOVAE,
xCMOVB, xCMOVBE,
xCMOVG, xCMOVGE,
xCMOVL, xCMOVLE,
xCMOVZ, xCMOVE,
xCMOVNZ, xCMOVNE,
xCMOVO, xCMOVNO,
xCMOVC, xCMOVNC,
xCMOVS, xCMOVNS,
xCMOVPE, xCMOVPO;
// ------------------------------------------------------------------------
extern const xImpl_Set
xSETA, xSETAE,
xSETB, xSETBE,
xSETG, xSETGE,
xSETL, xSETLE,
xSETZ, xSETE,
xSETNZ, xSETNE,
xSETO, xSETNO,
xSETC, xSETNC,
xSETS, xSETNS,
xSETPE, xSETPO;
// ------------------------------------------------------------------------
// BMI extra instruction requires BMI1/BMI2
extern const xImplBMI_RVM xMULX, xPDEP, xPEXT, xANDN_S; // Warning xANDN is already used by SSE
//////////////////////////////////////////////////////////////////////////////////////////
// Miscellaneous Instructions
// These are all defined inline or in ix86.cpp.
//
extern void xBSWAP( const xRegister32or64& to );
// ----- Lea Instructions (Load Effective Address) -----
// Note: alternate (void*) forms of these instructions are not provided since those
// forms are functionally equivalent to Mov reg,imm, and thus better written as MOVs
// instead.
extern void xLEA( xRegister64 to, const xIndirectVoid& src, bool preserve_flags=false );
extern void xLEA( xRegister32 to, const xIndirectVoid& src, bool preserve_flags=false );
extern void xLEA( xRegister16 to, const xIndirectVoid& src, bool preserve_flags=false );
// ----- Push / Pop Instructions -----
// Note: pushad/popad implementations are intentionally left out. The instructions are
// invalid in x64, and are super slow on x32. Use multiple Push/Pop instructions instead.
extern void xPOP( const xIndirectVoid& from );
extern void xPUSH( const xIndirectVoid& from );
extern void xPOP( xRegister32or64 from );
extern void xPUSH( u32 imm );
extern void xPUSH( xRegister32or64 from );
// pushes the EFLAGS register onto the stack
extern void xPUSHFD();
// pops the EFLAGS register from the stack
extern void xPOPFD();
// ----- Miscellaneous Instructions -----
// Various Instructions with no parameter and no special encoding logic.
extern void xLEAVE();
extern void xRET();
extern void xCBW();
extern void xCWD();
extern void xCDQ();
extern void xCWDE();
extern void xLAHF();
extern void xSAHF();
extern void xSTC();
extern void xCLC();
// NOP 1-byte
extern void xNOP();
extern void xINT( u8 imm );
extern void xINTO();
//////////////////////////////////////////////////////////////////////////////////////////
// Helper object to handle the various functions ABI
class xScopedStackFrame
{
bool m_base_frame;
bool m_save_base_pointer;
int m_offset;
public:
xScopedStackFrame(bool base_frame, bool save_base_pointer = false, int offset = 0);
~xScopedStackFrame();
};
//////////////////////////////////////////////////////////////////////////////////////////
// JMP / Jcc Instructions!
extern void xJcc( JccComparisonType comparison, const void* target );
extern s8* xJcc8( JccComparisonType comparison=Jcc_Unconditional, s8 displacement=0 );
extern s32* xJcc32( JccComparisonType comparison=Jcc_Unconditional, s32 displacement=0 );
// ------------------------------------------------------------------------
// Conditional jumps to fixed targets.
// Jumps accept any pointer as a valid target (function or data), and will generate either
// 8 or 32 bit displacement versions of the jump, depending on relative displacement of
// the target (efficient!)
//
template< typename T > __fi void xJE( T* func ) { xJcc( Jcc_Equal, (void*)(uptr)func ); }
template< typename T > __fi void xJZ( T* func ) { xJcc( Jcc_Zero, (void*)(uptr)func ); }
template< typename T > __fi void xJNE( T* func ) { xJcc( Jcc_NotEqual, (void*)(uptr)func ); }
template< typename T > __fi void xJNZ( T* func ) { xJcc( Jcc_NotZero, (void*)(uptr)func ); }
template< typename T > __fi void xJO( T* func ) { xJcc( Jcc_Overflow, (void*)(uptr)func ); }
template< typename T > __fi void xJNO( T* func ) { xJcc( Jcc_NotOverflow, (void*)(uptr)func ); }
template< typename T > __fi void xJC( T* func ) { xJcc( Jcc_Carry, (void*)(uptr)func ); }
template< typename T > __fi void xJNC( T* func ) { xJcc( Jcc_NotCarry, (void*)(uptr)func ); }
template< typename T > __fi void xJS( T* func ) { xJcc( Jcc_Signed, (void*)(uptr)func ); }
template< typename T > __fi void xJNS( T* func ) { xJcc( Jcc_Unsigned, (void*)(uptr)func ); }
template< typename T > __fi void xJPE( T* func ) { xJcc( Jcc_ParityEven, (void*)(uptr)func ); }
template< typename T > __fi void xJPO( T* func ) { xJcc( Jcc_ParityOdd, (void*)(uptr)func ); }
template< typename T > __fi void xJL( T* func ) { xJcc( Jcc_Less, (void*)(uptr)func ); }
template< typename T > __fi void xJLE( T* func ) { xJcc( Jcc_LessOrEqual, (void*)(uptr)func ); }
template< typename T > __fi void xJG( T* func ) { xJcc( Jcc_Greater, (void*)(uptr)func ); }
template< typename T > __fi void xJGE( T* func ) { xJcc( Jcc_GreaterOrEqual, (void*)(uptr)func ); }
template< typename T > __fi void xJB( T* func ) { xJcc( Jcc_Below, (void*)(uptr)func ); }
template< typename T > __fi void xJBE( T* func ) { xJcc( Jcc_BelowOrEqual, (void*)(uptr)func ); }
template< typename T > __fi void xJA( T* func ) { xJcc( Jcc_Above, (void*)(uptr)func ); }
template< typename T > __fi void xJAE( T* func ) { xJcc( Jcc_AboveOrEqual, (void*)(uptr)func ); }
// ------------------------------------------------------------------------
// Forward Jump Helpers (act as labels!)
#define DEFINE_FORWARD_JUMP( label, cond ) \
template< typename OperandType > \
class xForward##label : public xForwardJump<OperandType> \
{ \
public: \
xForward##label() : xForwardJump<OperandType>( cond ) {} \
};
// ------------------------------------------------------------------------
// Note: typedefs below are defined individually in order to appease Intellisense
// resolution. Including them into the class definition macro above breaks it.
typedef xForwardJump<s8> xForwardJump8;
typedef xForwardJump<s32> xForwardJump32;
DEFINE_FORWARD_JUMP( JA, Jcc_Above );
DEFINE_FORWARD_JUMP( JB, Jcc_Below );
DEFINE_FORWARD_JUMP( JAE, Jcc_AboveOrEqual );
DEFINE_FORWARD_JUMP( JBE, Jcc_BelowOrEqual );
typedef xForwardJA<s8> xForwardJA8;
typedef xForwardJA<s32> xForwardJA32;
typedef xForwardJB<s8> xForwardJB8;
typedef xForwardJB<s32> xForwardJB32;
typedef xForwardJAE<s8> xForwardJAE8;
typedef xForwardJAE<s32> xForwardJAE32;
typedef xForwardJBE<s8> xForwardJBE8;
typedef xForwardJBE<s32> xForwardJBE32;
DEFINE_FORWARD_JUMP( JG, Jcc_Greater );
DEFINE_FORWARD_JUMP( JL, Jcc_Less );
DEFINE_FORWARD_JUMP( JGE, Jcc_GreaterOrEqual );
DEFINE_FORWARD_JUMP( JLE, Jcc_LessOrEqual );
typedef xForwardJG<s8> xForwardJG8;
typedef xForwardJG<s32> xForwardJG32;
typedef xForwardJL<s8> xForwardJL8;
typedef xForwardJL<s32> xForwardJL32;
typedef xForwardJGE<s8> xForwardJGE8;
typedef xForwardJGE<s32> xForwardJGE32;
typedef xForwardJLE<s8> xForwardJLE8;
typedef xForwardJLE<s32> xForwardJLE32;
DEFINE_FORWARD_JUMP( JZ, Jcc_Zero );
DEFINE_FORWARD_JUMP( JE, Jcc_Equal );
DEFINE_FORWARD_JUMP( JNZ, Jcc_NotZero );
DEFINE_FORWARD_JUMP( JNE, Jcc_NotEqual );
typedef xForwardJZ<s8> xForwardJZ8;
typedef xForwardJZ<s32> xForwardJZ32;
typedef xForwardJE<s8> xForwardJE8;
typedef xForwardJE<s32> xForwardJE32;
typedef xForwardJNZ<s8> xForwardJNZ8;
typedef xForwardJNZ<s32> xForwardJNZ32;
typedef xForwardJNE<s8> xForwardJNE8;
typedef xForwardJNE<s32> xForwardJNE32;
DEFINE_FORWARD_JUMP( JS, Jcc_Signed );
DEFINE_FORWARD_JUMP( JNS, Jcc_Unsigned );
typedef xForwardJS<s8> xForwardJS8;
typedef xForwardJS<s32> xForwardJS32;
typedef xForwardJNS<s8> xForwardJNS8;
typedef xForwardJNS<s32> xForwardJNS32;
DEFINE_FORWARD_JUMP( JO, Jcc_Overflow );
DEFINE_FORWARD_JUMP( JNO, Jcc_NotOverflow );
typedef xForwardJO<s8> xForwardJO8;
typedef xForwardJO<s32> xForwardJO32;
typedef xForwardJNO<s8> xForwardJNO8;
typedef xForwardJNO<s32> xForwardJNO32;
DEFINE_FORWARD_JUMP( JC, Jcc_Carry );
DEFINE_FORWARD_JUMP( JNC, Jcc_NotCarry );
typedef xForwardJC<s8> xForwardJC8;
typedef xForwardJC<s32> xForwardJC32;
typedef xForwardJNC<s8> xForwardJNC8;
typedef xForwardJNC<s32> xForwardJNC32;
DEFINE_FORWARD_JUMP( JPE, Jcc_ParityEven );
DEFINE_FORWARD_JUMP( JPO, Jcc_ParityOdd );
typedef xForwardJPE<s8> xForwardJPE8;
typedef xForwardJPE<s32> xForwardJPE32;
typedef xForwardJPO<s8> xForwardJPO8;
typedef xForwardJPO<s32> xForwardJPO32;
// ------------------------------------------------------------------------
extern void xEMMS();
extern void xSTMXCSR( const xIndirect32& dest );
extern void xLDMXCSR( const xIndirect32& src );
extern void xFXSAVE( const xIndirectVoid& dest );
extern void xFXRSTOR( const xIndirectVoid& src );
extern void xMOVDZX( const xRegisterSSE& to, const xRegister32or64& from );
extern void xMOVDZX( const xRegisterSSE& to, const xIndirectVoid& src );
extern void xMOVD( const xRegister32or64& to, const xRegisterSSE& from );
extern void xMOVD( const xIndirectVoid& dest, const xRegisterSSE& from );
extern void xMOVQ( const xIndirectVoid& dest, const xRegisterSSE& from );
extern void xMOVQZX( const xRegisterSSE& to, const xIndirectVoid& src );
extern void xMOVQZX( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xMOVSS( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xMOVSS( const xIndirectVoid& to, const xRegisterSSE& from );
extern void xMOVSD( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xMOVSD( const xIndirectVoid& to, const xRegisterSSE& from );
extern void xMOVSSZX( const xRegisterSSE& to, const xIndirectVoid& from );
extern void xMOVSDZX( const xRegisterSSE& to, const xIndirectVoid& from );
extern void xMOVNTDQA( const xRegisterSSE& to, const xIndirectVoid& from );
extern void xMOVNTDQA( const xIndirectVoid& to, const xRegisterSSE& from );
extern void xMOVNTPD( const xIndirectVoid& to, const xRegisterSSE& from );
extern void xMOVNTPS( const xIndirectVoid& to, const xRegisterSSE& from );
extern void xMOVMSKPS( const xRegister32or64& to, const xRegisterSSE& from );
extern void xMOVMSKPD( const xRegister32or64& to, const xRegisterSSE& from );
extern void xMASKMOV( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xPMOVMSKB( const xRegister32or64& to, const xRegisterSSE& from );
extern void xPALIGNR( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 );
// ------------------------------------------------------------------------
extern const xImplSimd_MoveSSE xMOVAPS;
extern const xImplSimd_MoveSSE xMOVUPS;
extern const xImplSimd_MoveSSE xMOVAPD;
extern const xImplSimd_MoveSSE xMOVUPD;
#ifdef ALWAYS_USE_MOVAPS
extern const xImplSimd_MoveSSE xMOVDQA;
extern const xImplSimd_MoveSSE xMOVDQU;
#else
extern const xImplSimd_MoveDQ xMOVDQA;
extern const xImplSimd_MoveDQ xMOVDQU;
#endif
extern const xImplSimd_MovHL xMOVH;
extern const xImplSimd_MovHL xMOVL;
extern const xImplSimd_MovHL_RtoR xMOVLH;
extern const xImplSimd_MovHL_RtoR xMOVHL;
extern const xImplSimd_Blend xBLEND;
extern const xImplSimd_PMove xPMOVSX;
extern const xImplSimd_PMove xPMOVZX;
extern const xImplSimd_DestRegSSE xMOVSLDUP;
extern const xImplSimd_DestRegSSE xMOVSHDUP;
extern void xINSERTPS( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 );
extern void xINSERTPS( const xRegisterSSE& to, const xIndirect32& from, u8 imm8 );
extern void xEXTRACTPS( const xRegister32or64& to, const xRegisterSSE& from, u8 imm8 );
extern void xEXTRACTPS( const xIndirect32& dest, const xRegisterSSE& from, u8 imm8 );
// ------------------------------------------------------------------------
extern const xImplSimd_DestRegEither xPAND;
extern const xImplSimd_DestRegEither xPANDN;
extern const xImplSimd_DestRegEither xPOR;
extern const xImplSimd_DestRegEither xPXOR;
extern const xImplSimd_Shuffle xSHUF;
// ------------------------------------------------------------------------
extern const xImplSimd_DestRegSSE xPTEST;
extern const xImplSimd_MinMax xMIN;
extern const xImplSimd_MinMax xMAX;
extern const xImplSimd_Compare xCMPEQ, xCMPLT,
xCMPLE, xCMPUNORD,
xCMPNE, xCMPNLT,
xCMPNLE,xCMPORD;
extern const xImplSimd_COMI xCOMI;
extern const xImplSimd_COMI xUCOMI;
extern const xImplSimd_PCompare xPCMP;
extern const xImplSimd_PMinMax xPMIN;
extern const xImplSimd_PMinMax xPMAX;
// ------------------------------------------------------------------------
//
//
extern void xCVTDQ2PD( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTDQ2PD( const xRegisterSSE& to, const xIndirect64& from );
extern void xCVTDQ2PS( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTDQ2PS( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTPD2DQ( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTPD2PS( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTPD2PS( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTPI2PD( const xRegisterSSE& to, const xIndirect64& from );
extern void xCVTPI2PS( const xRegisterSSE& to, const xIndirect64& from );
extern void xCVTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTPS2DQ( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTPS2PD( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTPS2PD( const xRegisterSSE& to, const xIndirect64& from );
extern void xCVTSD2SI( const xRegister32or64& to, const xRegisterSSE& from );
extern void xCVTSD2SI( const xRegister32or64& to, const xIndirect64& from );
extern void xCVTSD2SS( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTSD2SS( const xRegisterSSE& to, const xIndirect64& from );
extern void xCVTSI2SS( const xRegisterSSE& to, const xRegister32or64& from );
extern void xCVTSI2SS( const xRegisterSSE& to, const xIndirect32& from );
extern void xCVTSS2SD( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTSS2SD( const xRegisterSSE& to, const xIndirect32& from );
extern void xCVTSS2SI( const xRegister32or64& to, const xRegisterSSE& from );
extern void xCVTSS2SI( const xRegister32or64& to, const xIndirect32& from );
extern void xCVTTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTTPD2DQ( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTTPS2DQ( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTTSD2SI( const xRegister32or64& to, const xRegisterSSE& from );
extern void xCVTTSD2SI( const xRegister32or64& to, const xIndirect64& from );
extern void xCVTTSS2SI( const xRegister32or64& to, const xRegisterSSE& from );
extern void xCVTTSS2SI( const xRegister32or64& to, const xIndirect32& from );
// ------------------------------------------------------------------------
extern const xImplSimd_AndNot xANDN;
extern const xImplSimd_rSqrt xRCP;
extern const xImplSimd_rSqrt xRSQRT;
extern const xImplSimd_Sqrt xSQRT;
extern const xImplSimd_Shift xPSLL;
extern const xImplSimd_Shift xPSRL;
extern const xImplSimd_ShiftWithoutQ xPSRA;
extern const xImplSimd_AddSub xPADD;
extern const xImplSimd_AddSub xPSUB;
extern const xImplSimd_PMul xPMUL;
extern const xImplSimd_PAbsolute xPABS;
extern const xImplSimd_PSign xPSIGN;
extern const xImplSimd_PMultAdd xPMADD;
extern const xImplSimd_HorizAdd xHADD;
extern const xImplSimd_DotProduct xDP;
extern const xImplSimd_Round xROUND;
extern const xImplSimd_PShuffle xPSHUF;
extern const SimdImpl_PUnpack xPUNPCK;
extern const xImplSimd_Unpack xUNPCK;
extern const SimdImpl_Pack xPACK;
extern const xImplSimd_PInsert xPINSR;
extern const SimdImpl_PExtract xPEXTR;
extern const xImpl_FastCall xFastCall;
// ------------------------------------------------------------------------
extern const xImpl_CMov xCMOVA, xCMOVAE,
xCMOVB, xCMOVBE,
xCMOVG, xCMOVGE,
xCMOVL, xCMOVLE,
xCMOVZ, xCMOVE,
xCMOVNZ, xCMOVNE,
xCMOVO, xCMOVNO,
xCMOVC, xCMOVNC,
xCMOVS, xCMOVNS,
xCMOVPE, xCMOVPO;
// ------------------------------------------------------------------------
extern const xImpl_Set xSETA, xSETAE,
xSETB, xSETBE,
xSETG, xSETGE,
xSETL, xSETLE,
xSETZ, xSETE,
xSETNZ, xSETNE,
xSETO, xSETNO,
xSETC, xSETNC,
xSETS, xSETNS,
xSETPE, xSETPO;
// ------------------------------------------------------------------------
// BMI extra instruction requires BMI1/BMI2
extern const xImplBMI_RVM xMULX, xPDEP, xPEXT, xANDN_S; // Warning xANDN is already used by SSE
//////////////////////////////////////////////////////////////////////////////////////////
// Miscellaneous Instructions
// These are all defined inline or in ix86.cpp.
//
extern void xBSWAP(const xRegister32or64 &to);
// ----- Lea Instructions (Load Effective Address) -----
// Note: alternate (void*) forms of these instructions are not provided since those
// forms are functionally equivalent to Mov reg,imm, and thus better written as MOVs
// instead.
extern void xLEA(xRegister64 to, const xIndirectVoid &src, bool preserve_flags = false);
extern void xLEA(xRegister32 to, const xIndirectVoid &src, bool preserve_flags = false);
extern void xLEA(xRegister16 to, const xIndirectVoid &src, bool preserve_flags = false);
// ----- Push / Pop Instructions -----
// Note: pushad/popad implementations are intentionally left out. The instructions are
// invalid in x64, and are super slow on x32. Use multiple Push/Pop instructions instead.
extern void xPOP(const xIndirectVoid &from);
extern void xPUSH(const xIndirectVoid &from);
extern void xPOP(xRegister32or64 from);
extern void xPUSH(u32 imm);
extern void xPUSH(xRegister32or64 from);
// pushes the EFLAGS register onto the stack
extern void xPUSHFD();
// pops the EFLAGS register from the stack
extern void xPOPFD();
// ----- Miscellaneous Instructions -----
// Various Instructions with no parameter and no special encoding logic.
extern void xLEAVE();
extern void xRET();
extern void xCBW();
extern void xCWD();
extern void xCDQ();
extern void xCWDE();
extern void xLAHF();
extern void xSAHF();
extern void xSTC();
extern void xCLC();
// NOP 1-byte
extern void xNOP();
extern void xINT(u8 imm);
extern void xINTO();
//////////////////////////////////////////////////////////////////////////////////////////
// Helper object to handle the various functions ABI
class xScopedStackFrame
{
bool m_base_frame;
bool m_save_base_pointer;
int m_offset;
public:
xScopedStackFrame(bool base_frame, bool save_base_pointer = false, int offset = 0);
~xScopedStackFrame();
};
//////////////////////////////////////////////////////////////////////////////////////////
// JMP / Jcc Instructions!
extern void xJcc(JccComparisonType comparison, const void *target);
extern s8 *xJcc8(JccComparisonType comparison = Jcc_Unconditional, s8 displacement = 0);
extern s32 *xJcc32(JccComparisonType comparison = Jcc_Unconditional, s32 displacement = 0);
// ------------------------------------------------------------------------
// Conditional jumps to fixed targets.
// Jumps accept any pointer as a valid target (function or data), and will generate either
// 8 or 32 bit displacement versions of the jump, depending on relative displacement of
// the target (efficient!)
//
template <typename T>
__fi void xJE(T *func)
{
xJcc(Jcc_Equal, (void *)(uptr)func);
}
template <typename T>
__fi void xJZ(T *func)
{
xJcc(Jcc_Zero, (void *)(uptr)func);
}
template <typename T>
__fi void xJNE(T *func)
{
xJcc(Jcc_NotEqual, (void *)(uptr)func);
}
template <typename T>
__fi void xJNZ(T *func)
{
xJcc(Jcc_NotZero, (void *)(uptr)func);
}
template <typename T>
__fi void xJO(T *func)
{
xJcc(Jcc_Overflow, (void *)(uptr)func);
}
template <typename T>
__fi void xJNO(T *func)
{
xJcc(Jcc_NotOverflow, (void *)(uptr)func);
}
template <typename T>
__fi void xJC(T *func)
{
xJcc(Jcc_Carry, (void *)(uptr)func);
}
template <typename T>
__fi void xJNC(T *func)
{
xJcc(Jcc_NotCarry, (void *)(uptr)func);
}
template <typename T>
__fi void xJS(T *func)
{
xJcc(Jcc_Signed, (void *)(uptr)func);
}
template <typename T>
__fi void xJNS(T *func)
{
xJcc(Jcc_Unsigned, (void *)(uptr)func);
}
template <typename T>
__fi void xJPE(T *func)
{
xJcc(Jcc_ParityEven, (void *)(uptr)func);
}
template <typename T>
__fi void xJPO(T *func)
{
xJcc(Jcc_ParityOdd, (void *)(uptr)func);
}
template <typename T>
__fi void xJL(T *func)
{
xJcc(Jcc_Less, (void *)(uptr)func);
}
template <typename T>
__fi void xJLE(T *func)
{
xJcc(Jcc_LessOrEqual, (void *)(uptr)func);
}
template <typename T>
__fi void xJG(T *func)
{
xJcc(Jcc_Greater, (void *)(uptr)func);
}
template <typename T>
__fi void xJGE(T *func)
{
xJcc(Jcc_GreaterOrEqual, (void *)(uptr)func);
}
template <typename T>
__fi void xJB(T *func)
{
xJcc(Jcc_Below, (void *)(uptr)func);
}
template <typename T>
__fi void xJBE(T *func)
{
xJcc(Jcc_BelowOrEqual, (void *)(uptr)func);
}
template <typename T>
__fi void xJA(T *func)
{
xJcc(Jcc_Above, (void *)(uptr)func);
}
template <typename T>
__fi void xJAE(T *func)
{
xJcc(Jcc_AboveOrEqual, (void *)(uptr)func);
}
// ------------------------------------------------------------------------
// Forward Jump Helpers (act as labels!)
#define DEFINE_FORWARD_JUMP(label, cond) \
template <typename OperandType> \
class xForward##label : public xForwardJump<OperandType> \
{ \
public: \
xForward##label() \
: xForwardJump<OperandType>(cond) \
{ \
} \
};
// ------------------------------------------------------------------------
// Note: typedefs below are defined individually in order to appease Intellisense
// resolution. Including them into the class definition macro above breaks it.
typedef xForwardJump<s8> xForwardJump8;
typedef xForwardJump<s32> xForwardJump32;
DEFINE_FORWARD_JUMP(JA, Jcc_Above);
DEFINE_FORWARD_JUMP(JB, Jcc_Below);
DEFINE_FORWARD_JUMP(JAE, Jcc_AboveOrEqual);
DEFINE_FORWARD_JUMP(JBE, Jcc_BelowOrEqual);
typedef xForwardJA<s8> xForwardJA8;
typedef xForwardJA<s32> xForwardJA32;
typedef xForwardJB<s8> xForwardJB8;
typedef xForwardJB<s32> xForwardJB32;
typedef xForwardJAE<s8> xForwardJAE8;
typedef xForwardJAE<s32> xForwardJAE32;
typedef xForwardJBE<s8> xForwardJBE8;
typedef xForwardJBE<s32> xForwardJBE32;
DEFINE_FORWARD_JUMP(JG, Jcc_Greater);
DEFINE_FORWARD_JUMP(JL, Jcc_Less);
DEFINE_FORWARD_JUMP(JGE, Jcc_GreaterOrEqual);
DEFINE_FORWARD_JUMP(JLE, Jcc_LessOrEqual);
typedef xForwardJG<s8> xForwardJG8;
typedef xForwardJG<s32> xForwardJG32;
typedef xForwardJL<s8> xForwardJL8;
typedef xForwardJL<s32> xForwardJL32;
typedef xForwardJGE<s8> xForwardJGE8;
typedef xForwardJGE<s32> xForwardJGE32;
typedef xForwardJLE<s8> xForwardJLE8;
typedef xForwardJLE<s32> xForwardJLE32;
DEFINE_FORWARD_JUMP(JZ, Jcc_Zero);
DEFINE_FORWARD_JUMP(JE, Jcc_Equal);
DEFINE_FORWARD_JUMP(JNZ, Jcc_NotZero);
DEFINE_FORWARD_JUMP(JNE, Jcc_NotEqual);
typedef xForwardJZ<s8> xForwardJZ8;
typedef xForwardJZ<s32> xForwardJZ32;
typedef xForwardJE<s8> xForwardJE8;
typedef xForwardJE<s32> xForwardJE32;
typedef xForwardJNZ<s8> xForwardJNZ8;
typedef xForwardJNZ<s32> xForwardJNZ32;
typedef xForwardJNE<s8> xForwardJNE8;
typedef xForwardJNE<s32> xForwardJNE32;
DEFINE_FORWARD_JUMP(JS, Jcc_Signed);
DEFINE_FORWARD_JUMP(JNS, Jcc_Unsigned);
typedef xForwardJS<s8> xForwardJS8;
typedef xForwardJS<s32> xForwardJS32;
typedef xForwardJNS<s8> xForwardJNS8;
typedef xForwardJNS<s32> xForwardJNS32;
DEFINE_FORWARD_JUMP(JO, Jcc_Overflow);
DEFINE_FORWARD_JUMP(JNO, Jcc_NotOverflow);
typedef xForwardJO<s8> xForwardJO8;
typedef xForwardJO<s32> xForwardJO32;
typedef xForwardJNO<s8> xForwardJNO8;
typedef xForwardJNO<s32> xForwardJNO32;
DEFINE_FORWARD_JUMP(JC, Jcc_Carry);
DEFINE_FORWARD_JUMP(JNC, Jcc_NotCarry);
typedef xForwardJC<s8> xForwardJC8;
typedef xForwardJC<s32> xForwardJC32;
typedef xForwardJNC<s8> xForwardJNC8;
typedef xForwardJNC<s32> xForwardJNC32;
DEFINE_FORWARD_JUMP(JPE, Jcc_ParityEven);
DEFINE_FORWARD_JUMP(JPO, Jcc_ParityOdd);
typedef xForwardJPE<s8> xForwardJPE8;
typedef xForwardJPE<s32> xForwardJPE32;
typedef xForwardJPO<s8> xForwardJPO8;
typedef xForwardJPO<s32> xForwardJPO32;
// ------------------------------------------------------------------------
extern void xEMMS();
extern void xSTMXCSR(const xIndirect32 &dest);
extern void xLDMXCSR(const xIndirect32 &src);
extern void xFXSAVE(const xIndirectVoid &dest);
extern void xFXRSTOR(const xIndirectVoid &src);
extern void xMOVDZX(const xRegisterSSE &to, const xRegister32or64 &from);
extern void xMOVDZX(const xRegisterSSE &to, const xIndirectVoid &src);
extern void xMOVD(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xMOVD(const xIndirectVoid &dest, const xRegisterSSE &from);
extern void xMOVQ(const xIndirectVoid &dest, const xRegisterSSE &from);
extern void xMOVQZX(const xRegisterSSE &to, const xIndirectVoid &src);
extern void xMOVQZX(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xMOVSS(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xMOVSS(const xIndirectVoid &to, const xRegisterSSE &from);
extern void xMOVSD(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xMOVSD(const xIndirectVoid &to, const xRegisterSSE &from);
extern void xMOVSSZX(const xRegisterSSE &to, const xIndirectVoid &from);
extern void xMOVSDZX(const xRegisterSSE &to, const xIndirectVoid &from);
extern void xMOVNTDQA(const xRegisterSSE &to, const xIndirectVoid &from);
extern void xMOVNTDQA(const xIndirectVoid &to, const xRegisterSSE &from);
extern void xMOVNTPD(const xIndirectVoid &to, const xRegisterSSE &from);
extern void xMOVNTPS(const xIndirectVoid &to, const xRegisterSSE &from);
extern void xMOVMSKPS(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xMOVMSKPD(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xMASKMOV(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xPMOVMSKB(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xPALIGNR(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm8);
// ------------------------------------------------------------------------
extern const xImplSimd_MoveSSE xMOVAPS;
extern const xImplSimd_MoveSSE xMOVUPS;
extern const xImplSimd_MoveSSE xMOVAPD;
extern const xImplSimd_MoveSSE xMOVUPD;
#ifdef ALWAYS_USE_MOVAPS
extern const xImplSimd_MoveSSE xMOVDQA;
extern const xImplSimd_MoveSSE xMOVDQU;
#else
extern const xImplSimd_MoveDQ xMOVDQA;
extern const xImplSimd_MoveDQ xMOVDQU;
#endif
extern const xImplSimd_MovHL xMOVH;
extern const xImplSimd_MovHL xMOVL;
extern const xImplSimd_MovHL_RtoR xMOVLH;
extern const xImplSimd_MovHL_RtoR xMOVHL;
extern const xImplSimd_Blend xBLEND;
extern const xImplSimd_PMove xPMOVSX;
extern const xImplSimd_PMove xPMOVZX;
extern const xImplSimd_DestRegSSE xMOVSLDUP;
extern const xImplSimd_DestRegSSE xMOVSHDUP;
extern void xINSERTPS(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm8);
extern void xINSERTPS(const xRegisterSSE &to, const xIndirect32 &from, u8 imm8);
extern void xEXTRACTPS(const xRegister32or64 &to, const xRegisterSSE &from, u8 imm8);
extern void xEXTRACTPS(const xIndirect32 &dest, const xRegisterSSE &from, u8 imm8);
// ------------------------------------------------------------------------
extern const xImplSimd_DestRegEither xPAND;
extern const xImplSimd_DestRegEither xPANDN;
extern const xImplSimd_DestRegEither xPOR;
extern const xImplSimd_DestRegEither xPXOR;
extern const xImplSimd_Shuffle xSHUF;
// ------------------------------------------------------------------------
extern const xImplSimd_DestRegSSE xPTEST;
extern const xImplSimd_MinMax xMIN;
extern const xImplSimd_MinMax xMAX;
extern const xImplSimd_Compare xCMPEQ, xCMPLT,
xCMPLE, xCMPUNORD,
xCMPNE, xCMPNLT,
xCMPNLE, xCMPORD;
extern const xImplSimd_COMI xCOMI;
extern const xImplSimd_COMI xUCOMI;
extern const xImplSimd_PCompare xPCMP;
extern const xImplSimd_PMinMax xPMIN;
extern const xImplSimd_PMinMax xPMAX;
// ------------------------------------------------------------------------
//
//
extern void xCVTDQ2PD(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTDQ2PD(const xRegisterSSE &to, const xIndirect64 &from);
extern void xCVTDQ2PS(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTDQ2PS(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTPD2DQ(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTPD2DQ(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTPD2PS(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTPD2PS(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTPI2PD(const xRegisterSSE &to, const xIndirect64 &from);
extern void xCVTPI2PS(const xRegisterSSE &to, const xIndirect64 &from);
extern void xCVTPS2DQ(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTPS2DQ(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTPS2PD(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTPS2PD(const xRegisterSSE &to, const xIndirect64 &from);
extern void xCVTSD2SI(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xCVTSD2SI(const xRegister32or64 &to, const xIndirect64 &from);
extern void xCVTSD2SS(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTSD2SS(const xRegisterSSE &to, const xIndirect64 &from);
extern void xCVTSI2SS(const xRegisterSSE &to, const xRegister32or64 &from);
extern void xCVTSI2SS(const xRegisterSSE &to, const xIndirect32 &from);
extern void xCVTSS2SD(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTSS2SD(const xRegisterSSE &to, const xIndirect32 &from);
extern void xCVTSS2SI(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xCVTSS2SI(const xRegister32or64 &to, const xIndirect32 &from);
extern void xCVTTPD2DQ(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTTPD2DQ(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTTPS2DQ(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTTPS2DQ(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTTSD2SI(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xCVTTSD2SI(const xRegister32or64 &to, const xIndirect64 &from);
extern void xCVTTSS2SI(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xCVTTSS2SI(const xRegister32or64 &to, const xIndirect32 &from);
// ------------------------------------------------------------------------
extern const xImplSimd_AndNot xANDN;
extern const xImplSimd_rSqrt xRCP;
extern const xImplSimd_rSqrt xRSQRT;
extern const xImplSimd_Sqrt xSQRT;
extern const xImplSimd_Shift xPSLL;
extern const xImplSimd_Shift xPSRL;
extern const xImplSimd_ShiftWithoutQ xPSRA;
extern const xImplSimd_AddSub xPADD;
extern const xImplSimd_AddSub xPSUB;
extern const xImplSimd_PMul xPMUL;
extern const xImplSimd_PAbsolute xPABS;
extern const xImplSimd_PSign xPSIGN;
extern const xImplSimd_PMultAdd xPMADD;
extern const xImplSimd_HorizAdd xHADD;
extern const xImplSimd_DotProduct xDP;
extern const xImplSimd_Round xROUND;
extern const xImplSimd_PShuffle xPSHUF;
extern const SimdImpl_PUnpack xPUNPCK;
extern const xImplSimd_Unpack xUNPCK;
extern const SimdImpl_Pack xPACK;
extern const xImplSimd_PInsert xPINSR;
extern const SimdImpl_PExtract xPEXTR;
}

View File

@ -19,156 +19,164 @@
#include "instructions.h"
namespace x86Emitter {
namespace x86Emitter
{
#define OpWriteSSE( pre, op ) xOpWrite0F( pre, op, to, from )
#define OpWriteSSE(pre, op) xOpWrite0F(pre, op, to, from)
extern void SimdPrefix( u8 prefix, u16 opcode );
extern void EmitSibMagic( uint regfield, const void* address );
extern void EmitSibMagic( uint regfield, const xIndirectVoid& info );
extern void EmitSibMagic( uint reg1, const xRegisterBase& reg2 );
extern void EmitSibMagic( const xRegisterBase& reg1, const xRegisterBase& reg2 );
extern void EmitSibMagic( const xRegisterBase& reg1, const void* src );
extern void EmitSibMagic( const xRegisterBase& reg1, const xIndirectVoid& sib );
extern void SimdPrefix(u8 prefix, u16 opcode);
extern void EmitSibMagic(uint regfield, const void *address);
extern void EmitSibMagic(uint regfield, const xIndirectVoid &info);
extern void EmitSibMagic(uint reg1, const xRegisterBase &reg2);
extern void EmitSibMagic(const xRegisterBase &reg1, const xRegisterBase &reg2);
extern void EmitSibMagic(const xRegisterBase &reg1, const void *src);
extern void EmitSibMagic(const xRegisterBase &reg1, const xIndirectVoid &sib);
extern void EmitRex( uint regfield, const void* address );
extern void EmitRex( uint regfield, const xIndirectVoid& info );
extern void EmitRex( uint reg1, const xRegisterBase& reg2 );
extern void EmitRex( const xRegisterBase& reg1, const xRegisterBase& reg2 );
extern void EmitRex( const xRegisterBase& reg1, const void* src );
extern void EmitRex( const xRegisterBase& reg1, const xIndirectVoid& sib );
extern void EmitRex(uint regfield, const void *address);
extern void EmitRex(uint regfield, const xIndirectVoid &info);
extern void EmitRex(uint reg1, const xRegisterBase &reg2);
extern void EmitRex(const xRegisterBase &reg1, const xRegisterBase &reg2);
extern void EmitRex(const xRegisterBase &reg1, const void *src);
extern void EmitRex(const xRegisterBase &reg1, const xIndirectVoid &sib);
extern void _xMovRtoR( const xRegisterInt& to, const xRegisterInt& from );
template< typename T > inline
void xWrite( T val )
{
*(T*)x86Ptr = val;
x86Ptr += sizeof(T);
}
template< typename T1, typename T2 > __emitinline
void xOpWrite( u8 prefix, u8 opcode, const T1& param1, const T2& param2 )
{
if( prefix != 0 ) xWrite8( prefix );
EmitRex( param1, param2 );
xWrite8( opcode );
EmitSibMagic( param1, param2 );
}
template< typename T1, typename T2 > __emitinline
void xOpAccWrite( u8 prefix, u8 opcode, const T1& param1, const T2& param2 )
{
if( prefix != 0 ) xWrite8( prefix );
EmitRex( param1, param2 );
xWrite8( opcode );
}
//////////////////////////////////////////////////////////////////////////////////////////
// emitter helpers for xmm instruction with prefixes, most of which are using
// the basic opcode format (items inside braces denote optional or conditional
// emission):
//
// [Prefix] / 0x0f / [OpcodePrefix] / Opcode / ModRM+[SibSB]
//
// Prefixes are typically 0x66, 0xf2, or 0xf3. OpcodePrefixes are either 0x38 or
// 0x3a [and other value will result in assertion failue].
//
template< typename T1, typename T2 > __emitinline
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2 )
{
if( prefix != 0 ) xWrite8( prefix );
EmitRex( param1, param2 );
SimdPrefix( 0, opcode );
EmitSibMagic( param1, param2 );
}
template< typename T1, typename T2 > __emitinline
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2, u8 imm8 )
{
xOpWrite0F( prefix, opcode, param1, param2 );
xWrite8( imm8 );
}
template< typename T1, typename T2 > __emitinline
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2 ) { xOpWrite0F( 0, opcode, param1, param2 ); }
template< typename T1, typename T2 > __emitinline
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2, u8 imm8 ) { xOpWrite0F( 0, opcode, param1, param2, imm8 ); }
// VEX 2 Bytes Prefix
template< typename T1, typename T2, typename T3 > __emitinline
void xOpWriteC5( u8 prefix, u8 opcode, const T1& param1, const T2& param2, const T3& param3 )
{
pxAssert( prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2 );
const xRegisterInt& reg = param1.IsReg() ? param1 : param2;
#ifdef __x86_64__
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
#else
u8 nR = 0x80;
#endif
u8 L = reg.IsWideSIMD() ? 4 : 0;
u8 nv = (~param2.GetId() & 0xF) << 3;
u8 p =
prefix == 0xF2 ? 3 :
prefix == 0xF3 ? 2 :
prefix == 0x66 ? 1 : 0;
xWrite8( 0xC5 );
xWrite8( nR | nv | L | p );
xWrite8( opcode );
EmitSibMagic( param1, param3 );
}
// VEX 3 Bytes Prefix
template< typename T1, typename T2, typename T3 > __emitinline
void xOpWriteC4( u8 prefix, u8 mb_prefix, u8 opcode, const T1& param1, const T2& param2, const T3& param3, int w = -1 )
{
pxAssert( prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2 );
pxAssert( mb_prefix == 0x0F || mb_prefix == 0x38 || mb_prefix == 0x3A );
const xRegisterInt& reg = param1.IsReg() ? param1 : param2;
#ifdef __x86_64__
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
u8 nB = param3.IsExtended() ? 0x00 : 0x20;
u8 nX = 0x40; // likely unused so hardwired to disabled
#else
u8 nR = 0x80;
u8 nB = 0x20;
u8 nX = 0x40;
#endif
u8 L = reg.IsWideSIMD() ? 4 : 0;
u8 W = (w == -1) ? (reg.GetOperandSize() == 8 ? 0x80 : 0) : // autodetect the size
0x80 * w; // take directly the W value
u8 nv = (~param2.GetId() & 0xF) << 3;
u8 p =
prefix == 0xF2 ? 3 :
prefix == 0xF3 ? 2 :
prefix == 0x66 ? 1 : 0;
u8 m =
mb_prefix == 0x3A ? 3 :
mb_prefix == 0x38 ? 2 : 1;
xWrite8( 0xC4 );
xWrite8( nR | nX | nB | m );
xWrite8( W | nv | L | p );
xWrite8( opcode );
EmitSibMagic( param1, param3 );
}
extern void _xMovRtoR(const xRegisterInt &to, const xRegisterInt &from);
template <typename T>
inline void xWrite(T val)
{
*(T *)x86Ptr = val;
x86Ptr += sizeof(T);
}
template <typename T1, typename T2>
__emitinline void xOpWrite(u8 prefix, u8 opcode, const T1 &param1, const T2 &param2)
{
if (prefix != 0)
xWrite8(prefix);
EmitRex(param1, param2);
xWrite8(opcode);
EmitSibMagic(param1, param2);
}
template <typename T1, typename T2>
__emitinline void xOpAccWrite(u8 prefix, u8 opcode, const T1 &param1, const T2 &param2)
{
if (prefix != 0)
xWrite8(prefix);
EmitRex(param1, param2);
xWrite8(opcode);
}
//////////////////////////////////////////////////////////////////////////////////////////
// emitter helpers for xmm instruction with prefixes, most of which are using
// the basic opcode format (items inside braces denote optional or conditional
// emission):
//
// [Prefix] / 0x0f / [OpcodePrefix] / Opcode / ModRM+[SibSB]
//
// Prefixes are typically 0x66, 0xf2, or 0xf3. OpcodePrefixes are either 0x38 or
// 0x3a [and other value will result in assertion failue].
//
template <typename T1, typename T2>
__emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1 &param1, const T2 &param2)
{
if (prefix != 0)
xWrite8(prefix);
EmitRex(param1, param2);
SimdPrefix(0, opcode);
EmitSibMagic(param1, param2);
}
template <typename T1, typename T2>
__emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1 &param1, const T2 &param2, u8 imm8)
{
xOpWrite0F(prefix, opcode, param1, param2);
xWrite8(imm8);
}
template <typename T1, typename T2>
__emitinline void xOpWrite0F(u16 opcode, const T1 &param1, const T2 &param2)
{
xOpWrite0F(0, opcode, param1, param2);
}
template <typename T1, typename T2>
__emitinline void xOpWrite0F(u16 opcode, const T1 &param1, const T2 &param2, u8 imm8)
{
xOpWrite0F(0, opcode, param1, param2, imm8);
}
// VEX 2 Bytes Prefix
template <typename T1, typename T2, typename T3>
__emitinline void xOpWriteC5(u8 prefix, u8 opcode, const T1 &param1, const T2 &param2, const T3 &param3)
{
pxAssert(prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2);
const xRegisterInt &reg = param1.IsReg() ? param1 : param2;
#ifdef __x86_64__
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
#else
u8 nR = 0x80;
#endif
u8 L = reg.IsWideSIMD() ? 4 : 0;
u8 nv = (~param2.GetId() & 0xF) << 3;
u8 p =
prefix == 0xF2 ? 3 :
prefix == 0xF3 ? 2 :
prefix == 0x66 ? 1 : 0;
xWrite8(0xC5);
xWrite8(nR | nv | L | p);
xWrite8(opcode);
EmitSibMagic(param1, param3);
}
// VEX 3 Bytes Prefix
template <typename T1, typename T2, typename T3>
__emitinline void xOpWriteC4(u8 prefix, u8 mb_prefix, u8 opcode, const T1 &param1, const T2 &param2, const T3 &param3, int w = -1)
{
pxAssert(prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2);
pxAssert(mb_prefix == 0x0F || mb_prefix == 0x38 || mb_prefix == 0x3A);
const xRegisterInt &reg = param1.IsReg() ? param1 : param2;
#ifdef __x86_64__
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
u8 nB = param3.IsExtended() ? 0x00 : 0x20;
u8 nX = 0x40; // likely unused so hardwired to disabled
#else
u8 nR = 0x80;
u8 nB = 0x20;
u8 nX = 0x40;
#endif
u8 L = reg.IsWideSIMD() ? 4 : 0;
u8 W = (w == -1) ? (reg.GetOperandSize() == 8 ? 0x80 : 0) : // autodetect the size
0x80 * w; // take directly the W value
u8 nv = (~param2.GetId() & 0xF) << 3;
u8 p =
prefix == 0xF2 ? 3 :
prefix == 0xF3 ? 2 :
prefix == 0x66 ? 1 : 0;
u8 m =
mb_prefix == 0x3A ? 3 :
mb_prefix == 0x38 ? 2 : 1;
xWrite8(0xC4);
xWrite8(nR | nX | nB | m);
xWrite8(W | nv | L | p);
xWrite8(opcode);
EmitSibMagic(param1, param3);
}
}

View File

@ -25,15 +25,15 @@
//------------------------------------------------------------------
// legacy jump/align functions
//------------------------------------------------------------------
ATTR_DEP extern void x86SetPtr( u8 *ptr );
ATTR_DEP extern void x86SetJ8( u8 *j8 );
ATTR_DEP extern void x86SetJ8A( u8 *j8 );
ATTR_DEP extern void x86SetJ16( u16 *j16 );
ATTR_DEP extern void x86SetJ16A( u16 *j16 );
ATTR_DEP extern void x86SetJ32( u32 *j32 );
ATTR_DEP extern void x86SetJ32A( u32 *j32 );
ATTR_DEP extern void x86Align( int bytes );
ATTR_DEP extern void x86AlignExecutable( int align );
ATTR_DEP extern void x86SetPtr(u8 *ptr);
ATTR_DEP extern void x86SetJ8(u8 *j8);
ATTR_DEP extern void x86SetJ8A(u8 *j8);
ATTR_DEP extern void x86SetJ16(u16 *j16);
ATTR_DEP extern void x86SetJ16A(u16 *j16);
ATTR_DEP extern void x86SetJ32(u32 *j32);
ATTR_DEP extern void x86SetJ32A(u32 *j32);
ATTR_DEP extern void x86Align(int bytes);
ATTR_DEP extern void x86AlignExecutable(int align);
//------------------------------------------------------------------
////////////////////////////////////
@ -41,55 +41,55 @@ ATTR_DEP extern void x86AlignExecutable( int align );
////////////////////////////////////
// jmp rel8
ATTR_DEP extern u8* JMP8( u8 to );
ATTR_DEP extern u8 *JMP8(u8 to);
// jmp rel32
ATTR_DEP extern u32* JMP32( uptr to );
ATTR_DEP extern u32 *JMP32(uptr to);
// jp rel8
ATTR_DEP extern u8* JP8( u8 to );
ATTR_DEP extern u8 *JP8(u8 to);
// jnp rel8
ATTR_DEP extern u8* JNP8( u8 to );
ATTR_DEP extern u8 *JNP8(u8 to);
// je rel8
ATTR_DEP extern u8* JE8( u8 to );
ATTR_DEP extern u8 *JE8(u8 to);
// jz rel8
ATTR_DEP extern u8* JZ8( u8 to );
ATTR_DEP extern u8 *JZ8(u8 to);
// jg rel8
ATTR_DEP extern u8* JG8( u8 to );
ATTR_DEP extern u8 *JG8(u8 to);
// jge rel8
ATTR_DEP extern u8* JGE8( u8 to );
ATTR_DEP extern u8 *JGE8(u8 to);
// js rel8
ATTR_DEP extern u8* JS8( u8 to );
ATTR_DEP extern u8 *JS8(u8 to);
// jns rel8
ATTR_DEP extern u8* JNS8( u8 to );
ATTR_DEP extern u8 *JNS8(u8 to);
// jl rel8
ATTR_DEP extern u8* JL8( u8 to );
ATTR_DEP extern u8 *JL8(u8 to);
// ja rel8
ATTR_DEP extern u8* JA8( u8 to );
ATTR_DEP extern u8 *JA8(u8 to);
// jae rel8
ATTR_DEP extern u8* JAE8( u8 to );
ATTR_DEP extern u8 *JAE8(u8 to);
// jb rel8
ATTR_DEP extern u8* JB8( u8 to );
ATTR_DEP extern u8 *JB8(u8 to);
// jbe rel8
ATTR_DEP extern u8* JBE8( u8 to );
ATTR_DEP extern u8 *JBE8(u8 to);
// jle rel8
ATTR_DEP extern u8* JLE8( u8 to );
ATTR_DEP extern u8 *JLE8(u8 to);
// jne rel8
ATTR_DEP extern u8* JNE8( u8 to );
ATTR_DEP extern u8 *JNE8(u8 to);
// jnz rel8
ATTR_DEP extern u8* JNZ8( u8 to );
ATTR_DEP extern u8 *JNZ8(u8 to);
// jng rel8
ATTR_DEP extern u8* JNG8( u8 to );
ATTR_DEP extern u8 *JNG8(u8 to);
// jnge rel8
ATTR_DEP extern u8* JNGE8( u8 to );
ATTR_DEP extern u8 *JNGE8(u8 to);
// jnl rel8
ATTR_DEP extern u8* JNL8( u8 to );
ATTR_DEP extern u8 *JNL8(u8 to);
// jnle rel8
ATTR_DEP extern u8* JNLE8( u8 to );
ATTR_DEP extern u8 *JNLE8(u8 to);
// jo rel8
ATTR_DEP extern u8* JO8( u8 to );
ATTR_DEP extern u8 *JO8(u8 to);
// jno rel8
ATTR_DEP extern u8* JNO8( u8 to );
ATTR_DEP extern u8 *JNO8(u8 to);
/*
// jb rel16
@ -103,51 +103,51 @@ ATTR_DEP extern u16* JZ16( u16 to );
*/
// jns rel32
ATTR_DEP extern u32* JNS32( u32 to );
ATTR_DEP extern u32 *JNS32(u32 to);
// js rel32
ATTR_DEP extern u32* JS32( u32 to );
ATTR_DEP extern u32 *JS32(u32 to);
// jb rel32
ATTR_DEP extern u32* JB32( u32 to );
ATTR_DEP extern u32 *JB32(u32 to);
// je rel32
ATTR_DEP extern u32* JE32( u32 to );
ATTR_DEP extern u32 *JE32(u32 to);
// jz rel32
ATTR_DEP extern u32* JZ32( u32 to );
ATTR_DEP extern u32 *JZ32(u32 to);
// jg rel32
ATTR_DEP extern u32* JG32( u32 to );
ATTR_DEP extern u32 *JG32(u32 to);
// jge rel32
ATTR_DEP extern u32* JGE32( u32 to );
ATTR_DEP extern u32 *JGE32(u32 to);
// jl rel32
ATTR_DEP extern u32* JL32( u32 to );
ATTR_DEP extern u32 *JL32(u32 to);
// jle rel32
ATTR_DEP extern u32* JLE32( u32 to );
ATTR_DEP extern u32 *JLE32(u32 to);
// jae rel32
ATTR_DEP extern u32* JAE32( u32 to );
ATTR_DEP extern u32 *JAE32(u32 to);
// jne rel32
ATTR_DEP extern u32* JNE32( u32 to );
ATTR_DEP extern u32 *JNE32(u32 to);
// jnz rel32
ATTR_DEP extern u32* JNZ32( u32 to );
ATTR_DEP extern u32 *JNZ32(u32 to);
// jng rel32
ATTR_DEP extern u32* JNG32( u32 to );
ATTR_DEP extern u32 *JNG32(u32 to);
// jnge rel32
ATTR_DEP extern u32* JNGE32( u32 to );
ATTR_DEP extern u32 *JNGE32(u32 to);
// jnl rel32
ATTR_DEP extern u32* JNL32( u32 to );
ATTR_DEP extern u32 *JNL32(u32 to);
// jnle rel32
ATTR_DEP extern u32* JNLE32( u32 to );
ATTR_DEP extern u32 *JNLE32(u32 to);
// jo rel32
ATTR_DEP extern u32* JO32( u32 to );
ATTR_DEP extern u32 *JO32(u32 to);
// jno rel32
ATTR_DEP extern u32* JNO32( u32 to );
ATTR_DEP extern u32 *JNO32(u32 to);
// js rel32
ATTR_DEP extern u32* JS32( u32 to );
ATTR_DEP extern u32 *JS32(u32 to);
//******************
// FPU instructions
//******************
// fld m32 to fpu reg stack
ATTR_DEP extern void FLD32( u32 from );
ATTR_DEP extern void FLD32(u32 from);
// fld st(i)
ATTR_DEP extern void FLD(int st);
// fld1 (push +1.0f on the stack)
@ -155,7 +155,7 @@ ATTR_DEP extern void FLD1();
// fld1 (push log_2 e on the stack)
ATTR_DEP extern void FLDL2E();
// fstp m32 from fpu reg stack
ATTR_DEP extern void FSTP32( u32 to );
ATTR_DEP extern void FSTP32(u32 to);
// fstp st(i)
ATTR_DEP extern void FSTP(int st);
@ -166,32 +166,32 @@ ATTR_DEP extern void F2XM1();
ATTR_DEP extern void FSCALE();
// fadd ST(0) to fpu reg stack ST(src)
ATTR_DEP extern void FADD320toR( x86IntRegType src );
ATTR_DEP extern void FADD320toR(x86IntRegType src);
// fsub ST(src) to fpu reg stack ST(0)
ATTR_DEP extern void FSUB32Rto0( x86IntRegType src );
ATTR_DEP extern void FSUB32Rto0(x86IntRegType src);
// fmul m32 to fpu reg stack
ATTR_DEP extern void FMUL32( u32 from );
ATTR_DEP extern void FMUL32(u32 from);
// fdiv m32 to fpu reg stack
ATTR_DEP extern void FDIV32( u32 from );
ATTR_DEP extern void FDIV32(u32 from);
// ftan fpu reg stack
ATTR_DEP extern void FPATAN( void );
ATTR_DEP extern void FPATAN(void);
// fsin fpu reg stack
ATTR_DEP extern void FSIN( void );
ATTR_DEP extern void FSIN(void);
//*********************
// SSE instructions *
//*********************
ATTR_DEP extern void SSE_MAXSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
ATTR_DEP extern void SSE_MINSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
ATTR_DEP extern void SSE_ADDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
ATTR_DEP extern void SSE_SUBSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
ATTR_DEP extern void SSE_MAXSS_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE_MINSS_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE_ADDSS_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE_SUBSS_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
//*********************
// SSE 2 Instructions*
//*********************
ATTR_DEP extern void SSE2_MAXSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
ATTR_DEP extern void SSE2_MINSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
ATTR_DEP extern void SSE2_ADDSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
ATTR_DEP extern void SSE2_SUBSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
ATTR_DEP extern void SSE2_MAXSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE2_MINSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE2_ADDSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE2_SUBSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);

View File

@ -31,11 +31,10 @@ using x86Emitter::xWrite64;
#include "legacy_types.h"
#include "legacy_instructions.h"
#define MEMADDR(addr, oplen) (addr)
extern void ModRM( uint mod, uint reg, uint rm );
extern void SibSB( uint ss, uint index, uint base );
extern void SET8R( int cc, int to );
extern u8* J8Rel( int cc, int to );
extern u32* J32Rel( int cc, u32 to );
#define MEMADDR(addr, oplen) (addr)
extern void ModRM(uint mod, uint reg, uint rm);
extern void SibSB(uint ss, uint index, uint base);
extern void SET8R(int cc, int to);
extern u8 *J8Rel(int cc, int to);
extern u32 *J32Rel(int cc, u32 to);

View File

@ -17,7 +17,7 @@
//#define SIB 4 // maps to ESP
//#define SIBDISP 5 // maps to EBP
#define DISP32 5 // maps to EBP
#define DISP32 5 // maps to EBP
// general types
typedef int x86IntRegType;

View File

@ -17,11 +17,10 @@
#include "x86emitter.h"
enum x86VendorType
{
x86Vendor_Intel = 0,
x86Vendor_AMD = 1,
x86Vendor_Unknown = 2
enum x86VendorType {
x86Vendor_Intel = 0,
x86Vendor_AMD = 1,
x86Vendor_Unknown = 2
};
// --------------------------------------------------------------------------------------
@ -30,110 +29,111 @@ enum x86VendorType
class x86capabilities
{
public:
bool isIdentified;
bool isIdentified;
public:
x86VendorType VendorID;
x86VendorType VendorID;
uint FamilyID; // Processor Family
uint Model; // Processor Model
uint TypeID; // Processor Type
uint StepID; // Stepping ID
uint FamilyID; // Processor Family
uint Model; // Processor Model
uint TypeID; // Processor Type
uint StepID; // Stepping ID
u32 Flags; // Feature Flags
u32 Flags2; // More Feature Flags
u32 EFlags; // Extended Feature Flags
u32 EFlags2; // Extended Feature Flags pg2
u32 SEFlag; // Structured Extended Feature Flags Enumeration
u32 Flags; // Feature Flags
u32 Flags2; // More Feature Flags
u32 EFlags; // Extended Feature Flags
u32 EFlags2; // Extended Feature Flags pg2
u32 SEFlag; // Structured Extended Feature Flags Enumeration
char VendorName[16]; // Vendor/Creator ID
char FamilyName[50]; // the original cpu name
char VendorName[16]; // Vendor/Creator ID
char FamilyName[50]; // the original cpu name
// ----------------------------------------------------------------------------
// x86 CPU Capabilities Section (all boolean flags!)
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// x86 CPU Capabilities Section (all boolean flags!)
// ----------------------------------------------------------------------------
union {
struct {
u32 hasFloatingPointUnit :1;
u32 hasVirtual8086ModeEnhancements :1;
u32 hasDebuggingExtensions :1;
u32 hasPageSizeExtensions :1;
u32 hasTimeStampCounter :1;
u32 hasModelSpecificRegisters :1;
u32 hasPhysicalAddressExtension :1;
u32 hasCOMPXCHG8BInstruction :1;
u32 hasAdvancedProgrammableInterruptController :1;
u32 hasSEPFastSystemCall :1;
u32 hasMemoryTypeRangeRegisters :1;
u32 hasPTEGlobalFlag :1;
u32 hasMachineCheckArchitecture :1;
u32 hasConditionalMoveAndCompareInstructions :1;
u32 hasFGPageAttributeTable :1;
u32 has36bitPageSizeExtension :1;
u32 hasProcessorSerialNumber :1;
u32 hasCFLUSHInstruction :1;
u32 hasDebugStore :1;
u32 hasACPIThermalMonitorAndClockControl :1;
u32 hasFastStreamingSIMDExtensionsSaveRestore :1;
u32 hasStreamingSIMDExtensions :1;
u32 hasStreamingSIMD2Extensions :1;
u32 hasSelfSnoop :1;
union
{
struct
{
u32 hasFloatingPointUnit : 1;
u32 hasVirtual8086ModeEnhancements : 1;
u32 hasDebuggingExtensions : 1;
u32 hasPageSizeExtensions : 1;
u32 hasTimeStampCounter : 1;
u32 hasModelSpecificRegisters : 1;
u32 hasPhysicalAddressExtension : 1;
u32 hasCOMPXCHG8BInstruction : 1;
u32 hasAdvancedProgrammableInterruptController : 1;
u32 hasSEPFastSystemCall : 1;
u32 hasMemoryTypeRangeRegisters : 1;
u32 hasPTEGlobalFlag : 1;
u32 hasMachineCheckArchitecture : 1;
u32 hasConditionalMoveAndCompareInstructions : 1;
u32 hasFGPageAttributeTable : 1;
u32 has36bitPageSizeExtension : 1;
u32 hasProcessorSerialNumber : 1;
u32 hasCFLUSHInstruction : 1;
u32 hasDebugStore : 1;
u32 hasACPIThermalMonitorAndClockControl : 1;
u32 hasFastStreamingSIMDExtensionsSaveRestore : 1;
u32 hasStreamingSIMDExtensions : 1;
u32 hasStreamingSIMD2Extensions : 1;
u32 hasSelfSnoop : 1;
// is TRUE for both multi-core and Hyperthreaded CPUs.
u32 hasMultiThreading :1;
// is TRUE for both multi-core and Hyperthreaded CPUs.
u32 hasMultiThreading : 1;
u32 hasThermalMonitor :1;
u32 hasIntel64BitArchitecture :1;
u32 hasStreamingSIMD3Extensions :1;
u32 hasSupplementalStreamingSIMD3Extensions :1;
u32 hasStreamingSIMD4Extensions :1;
u32 hasStreamingSIMD4Extensions2 :1;
u32 hasAVX :1;
u32 hasAVX2 :1;
u32 hasBMI1 :1;
u32 hasBMI2 :1;
u32 hasFMA :1;
u32 hasThermalMonitor : 1;
u32 hasIntel64BitArchitecture : 1;
u32 hasStreamingSIMD3Extensions : 1;
u32 hasSupplementalStreamingSIMD3Extensions : 1;
u32 hasStreamingSIMD4Extensions : 1;
u32 hasStreamingSIMD4Extensions2 : 1;
u32 hasAVX : 1;
u32 hasAVX2 : 1;
u32 hasBMI1 : 1;
u32 hasBMI2 : 1;
u32 hasFMA : 1;
// AMD-specific CPU Features
u32 hasAMD64BitArchitecture :1;
u32 hasStreamingSIMD4ExtensionsA :1;
};
// AMD-specific CPU Features
u32 hasAMD64BitArchitecture : 1;
u32 hasStreamingSIMD4ExtensionsA : 1;
};
u64 AllCapabilities;
};
u64 AllCapabilities;
};
// Core Counts!
u32 PhysicalCores;
u32 LogicalCores;
// Core Counts!
u32 PhysicalCores;
u32 LogicalCores;
public:
x86capabilities();
x86capabilities();
void Identify();
void CountCores();
wxString GetTypeName() const;
void Identify();
void CountCores();
wxString GetTypeName() const;
u32 CalculateMHz() const;
u32 CalculateMHz() const;
void SIMD_EstablishMXCSRmask();
void SIMD_EstablishMXCSRmask();
protected:
s64 _CPUSpeedHz( u64 time ) const;
void CountLogicalCores();
s64 _CPUSpeedHz(u64 time) const;
void CountLogicalCores();
};
enum SSE_RoundMode
{
SSE_RoundMode_FIRST = 0,
SSEround_Nearest = 0,
SSEround_NegInf,
SSEround_PosInf,
SSEround_Chop,
SSE_RoundMode_COUNT
enum SSE_RoundMode {
SSE_RoundMode_FIRST = 0,
SSEround_Nearest = 0,
SSEround_NegInf,
SSEround_PosInf,
SSEround_Chop,
SSE_RoundMode_COUNT
};
ImplementEnumOperators( SSE_RoundMode );
ImplementEnumOperators(SSE_RoundMode);
// --------------------------------------------------------------------------------------
// SSE_MXCSR - Control/Status Register (bitfield)
@ -147,56 +147,55 @@ ImplementEnumOperators( SSE_RoundMode );
//
union SSE_MXCSR
{
u32 bitmask;
struct
{
u32
InvalidOpFlag :1,
DenormalFlag :1,
DivideByZeroFlag :1,
OverflowFlag :1,
UnderflowFlag :1,
PrecisionFlag :1,
u32 bitmask;
struct
{
u32
InvalidOpFlag : 1,
DenormalFlag : 1,
DivideByZeroFlag : 1,
OverflowFlag : 1,
UnderflowFlag : 1,
PrecisionFlag : 1,
// This bit is supported only on SSE2 or better CPUs. Setting it to 1 on
// SSE1 cpus will result in an invalid instruction exception when executing
// LDMXSCR.
DenormalsAreZero :1,
// This bit is supported only on SSE2 or better CPUs. Setting it to 1 on
// SSE1 cpus will result in an invalid instruction exception when executing
// LDMXSCR.
DenormalsAreZero : 1,
InvalidOpMask :1,
DenormalMask :1,
DivideByZeroMask :1,
OverflowMask :1,
UnderflowMask :1,
PrecisionMask :1,
InvalidOpMask : 1,
DenormalMask : 1,
DivideByZeroMask : 1,
OverflowMask : 1,
UnderflowMask : 1,
PrecisionMask : 1,
RoundingControl :2,
FlushToZero :1;
};
RoundingControl : 2,
FlushToZero : 1;
};
SSE_RoundMode GetRoundMode() const;
SSE_MXCSR& SetRoundMode( SSE_RoundMode mode );
SSE_MXCSR& ClearExceptionFlags();
SSE_MXCSR& EnableExceptions();
SSE_MXCSR& DisableExceptions();
SSE_RoundMode GetRoundMode() const;
SSE_MXCSR &SetRoundMode(SSE_RoundMode mode);
SSE_MXCSR &ClearExceptionFlags();
SSE_MXCSR &EnableExceptions();
SSE_MXCSR &DisableExceptions();
SSE_MXCSR& ApplyReserveMask();
SSE_MXCSR &ApplyReserveMask();
bool operator ==( const SSE_MXCSR& right ) const
{
return bitmask == right.bitmask;
}
bool operator==(const SSE_MXCSR &right) const
{
return bitmask == right.bitmask;
}
bool operator !=( const SSE_MXCSR& right ) const
{
return bitmask != right.bitmask;
}
bool operator!=(const SSE_MXCSR &right) const
{
return bitmask != right.bitmask;
}
operator x86Emitter::xIndirect32() const;
operator x86Emitter::xIndirect32() const;
};
extern SSE_MXCSR MXCSR_Mask;
extern SSE_MXCSR MXCSR_Mask;
extern __aligned16 x86capabilities x86caps;

View File

@ -32,26 +32,30 @@
// CPU information support
#if defined(_WIN32)
#define cpuid __cpuid
#define cpuid __cpuid
#define cpuidex __cpuidex
#else
#include <cpuid.h>
static __inline__ __attribute__((always_inline)) void cpuidex(int CPUInfo[], const int InfoType, const int count) {
__cpuid_count(InfoType, count, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
static __inline__ __attribute__((always_inline)) void cpuidex(int CPUInfo[], const int InfoType, const int count)
{
__cpuid_count(InfoType, count, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
}
static __inline__ __attribute__((always_inline)) void cpuid(int CPUInfo[], const int InfoType) {
__cpuid(InfoType, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
static __inline__ __attribute__((always_inline)) void cpuid(int CPUInfo[], const int InfoType)
{
__cpuid(InfoType, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
}
static __inline__ __attribute__((always_inline)) unsigned long long _xgetbv(unsigned int index)
{
unsigned int eax, edx;
__asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index));
return ((unsigned long long)edx << 32) | eax;
unsigned int eax, edx;
__asm__ __volatile__("xgetbv"
: "=a"(eax), "=d"(edx)
: "c"(index));
return ((unsigned long long)edx << 32) | eax;
}
#endif
@ -61,16 +65,16 @@ static __inline__ __attribute__((always_inline)) unsigned long long _xgetbv(unsi
// Seriously what is so complicated to provided this bunch of intrinsics in clangs.
static unsigned int _rotr(unsigned int x, int s)
{
return (x >> s) | (x << (32 - s));
return (x >> s) | (x << (32 - s));
}
static unsigned int _rotl(unsigned int x, int s)
{
return (x << s) | (x >> (32 - s));
return (x << s) | (x >> (32 - s));
}
#endif
// Not correctly defined in GCC4.8 and below ! (dunno for VS)
#ifndef _MM_MK_INSERTPS_NDX
#define _MM_MK_INSERTPS_NDX(srcField, dstField, zeroMask) (((srcField)<<6) | ((dstField)<<4) | (zeroMask))
#define _MM_MK_INSERTPS_NDX(srcField, dstField, zeroMask) (((srcField) << 6) | ((dstField) << 4) | (zeroMask))
#endif

File diff suppressed because it is too large Load Diff

View File

@ -18,32 +18,32 @@
#include "PrecompiledHeader.h"
void* __fastcall _aligned_malloc(size_t size, size_t align)
void *__fastcall _aligned_malloc(size_t size, size_t align)
{
pxAssert( align < 0x10000 );
pxAssert(align < 0x10000);
#if defined(__USE_ISOC11) && !defined(ASAN_WORKAROUND) // not supported yet on gcc 4.9
return aligned_alloc(align, size);
return aligned_alloc(align, size);
#else
void *result = 0;
posix_memalign(&result, align, size);
return result;
void *result = 0;
posix_memalign(&result, align, size);
return result;
#endif
}
void* __fastcall pcsx2_aligned_realloc(void* handle, size_t new_size, size_t align, size_t old_size)
void *__fastcall pcsx2_aligned_realloc(void *handle, size_t new_size, size_t align, size_t old_size)
{
pxAssert( align < 0x10000 );
pxAssert(align < 0x10000);
void* newbuf = _aligned_malloc(new_size, align);
void *newbuf = _aligned_malloc(new_size, align);
if (newbuf != NULL && handle != NULL) {
memcpy(newbuf, handle, std::min(old_size, new_size));
_aligned_free(handle);
}
return newbuf;
if (newbuf != NULL && handle != NULL) {
memcpy(newbuf, handle, std::min(old_size, new_size));
_aligned_free(handle);
}
return newbuf;
}
__fi void _aligned_free(void* pmem)
__fi void _aligned_free(void *pmem)
{
free(pmem);
free(pmem);
}

View File

@ -16,62 +16,61 @@
#include "PrecompiledHeader.h"
#include "CheckedStaticBox.h"
CheckedStaticBox::CheckedStaticBox( wxWindow* parent, int orientation, const wxString& title )
: wxPanelWithHelpers( parent, wxVERTICAL )
, ThisSizer( *new wxStaticBoxSizer( orientation, this ) )
, ThisToggle( *new wxCheckBox( this, wxID_ANY, title, wxPoint( 8, 0 ) ) )
CheckedStaticBox::CheckedStaticBox(wxWindow *parent, int orientation, const wxString &title)
: wxPanelWithHelpers(parent, wxVERTICAL)
, ThisSizer(*new wxStaticBoxSizer(orientation, this))
, ThisToggle(*new wxCheckBox(this, wxID_ANY, title, wxPoint(8, 0)))
{
*this += ThisToggle;
*this += ThisSizer | pxExpand;
*this += ThisToggle;
*this += ThisSizer | pxExpand;
// Ensure that the right-side of the static group box isn't too cozy:
SetMinWidth( ThisToggle.GetSize().GetWidth() + 32 );
// Ensure that the right-side of the static group box isn't too cozy:
SetMinWidth(ThisToggle.GetSize().GetWidth() + 32);
Bind(wxEVT_CHECKBOX, &CheckedStaticBox::MainToggle_Click, this, ThisToggle.GetId());
Bind(wxEVT_CHECKBOX, &CheckedStaticBox::MainToggle_Click, this, ThisToggle.GetId());
}
// Event handler for click events for the main checkbox (default behavior: enables/disables all child controls)
// This function can be overridden to implement custom handling of check enable/disable behavior.
void CheckedStaticBox::MainToggle_Click( wxCommandEvent& evt )
void CheckedStaticBox::MainToggle_Click(wxCommandEvent &evt)
{
SetValue( evt.IsChecked() );
SetValue(evt.IsChecked());
}
// Sets the main checkbox status, and enables/disables all child controls
// bound to the StaticBox accordingly.
void CheckedStaticBox::SetValue( bool val )
void CheckedStaticBox::SetValue(bool val)
{
wxWindowList& list = GetChildren();
wxWindowList &list = GetChildren();
for( wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter)
{
wxWindow *current = *iter;
if( current != &ThisToggle )
current->Enable( val );
}
ThisToggle.SetValue( val );
for (wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter) {
wxWindow *current = *iter;
if (current != &ThisToggle)
current->Enable(val);
}
ThisToggle.SetValue(val);
}
bool CheckedStaticBox::GetValue() const
{
return ThisToggle.GetValue();
return ThisToggle.GetValue();
}
// This override is here so to only enable the children if both the main toggle and
// the enable request are true. If not, disable them!
bool CheckedStaticBox::Enable( bool enable )
bool CheckedStaticBox::Enable(bool enable)
{
if (!_parent::Enable(enable)) return false;
if (!_parent::Enable(enable))
return false;
bool val = enable && ThisToggle.GetValue();
wxWindowList& list = GetChildren();
bool val = enable && ThisToggle.GetValue();
wxWindowList &list = GetChildren();
for( wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter)
{
wxWindow *current = *iter;
if( current != &ThisToggle )
current->Enable( val );
}
for (wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter) {
wxWindow *current = *iter;
if (current != &ThisToggle)
current->Enable(val);
}
return true;
return true;
}

View File

@ -18,22 +18,22 @@
#include "TraceLog.h"
#include "TlsVariable.inl"
#include "RedtapeWindows.h" // nneded for OutputDebugString
#include "RedtapeWindows.h" // nneded for OutputDebugString
using namespace Threading;
// thread-local console indentation setting.
static DeclareTls(int) conlog_Indent( 0 );
static DeclareTls(int) conlog_Indent(0);
// thread-local console color storage.
static DeclareTls(ConsoleColors) conlog_Color( DefaultConsoleColor );
static DeclareTls(ConsoleColors) conlog_Color(DefaultConsoleColor);
#ifdef __POSIX__
static FILE *stdout_fp = stdout;
void Console_SetStdout(FILE *fp)
{
stdout_fp = fp;
stdout_fp = fp;
}
#endif
@ -44,33 +44,33 @@ void Console_SetStdout(FILE *fp)
// Important! Only Assert and Null console loggers are allowed during C++ startup init (when
// the program or DLL first loads). Other log targets rely on the static buffer and a
// threaded mutex lock, which are only valid after C++ initialization has finished.
void Console_SetActiveHandler( const IConsoleWriter& writer, FILE* flushfp )
void Console_SetActiveHandler(const IConsoleWriter &writer, FILE *flushfp)
{
pxAssertDev(
(writer.WriteRaw != NULL) && (writer.DoWriteLn != NULL) &&
(writer.Newline != NULL) && (writer.SetTitle != NULL) &&
(writer.DoSetColor != NULL),
"Invalid IConsoleWriter object! All function pointer interfaces must be implemented."
);
pxAssertDev(
(writer.WriteRaw != NULL) && (writer.DoWriteLn != NULL) &&
(writer.Newline != NULL) && (writer.SetTitle != NULL) &&
(writer.DoSetColor != NULL),
"Invalid IConsoleWriter object! All function pointer interfaces must be implemented.");
Console = writer;
DevConWriter = writer;
Console = writer;
DevConWriter = writer;
#ifdef PCSX2_DEBUG
DbgCon = writer;
DbgCon = writer;
#endif
}
// Writes text to the Visual Studio Output window (Microsoft Windows only).
// On all other platforms this pipes to Stdout instead.
void MSW_OutputDebugString( const wxString& text )
void MSW_OutputDebugString(const wxString &text)
{
#if defined(__WXMSW__) && !defined(__WXMICROWIN__)
static bool hasDebugger = wxIsDebuggerRunning();
if( hasDebugger ) OutputDebugString( text );
static bool hasDebugger = wxIsDebuggerRunning();
if (hasDebugger)
OutputDebugString(text);
#else
fputs(text.utf8_str(), stdout_fp);
fflush(stdout_fp);
fputs(text.utf8_str(), stdout_fp);
fflush(stdout_fp);
#endif
}
@ -79,23 +79,23 @@ void MSW_OutputDebugString( const wxString& text )
// ConsoleNull
// --------------------------------------------------------------------------------------
static void __concall ConsoleNull_SetTitle( const wxString& title ) {}
static void __concall ConsoleNull_DoSetColor( ConsoleColors color ) {}
static void __concall ConsoleNull_SetTitle(const wxString &title) {}
static void __concall ConsoleNull_DoSetColor(ConsoleColors color) {}
static void __concall ConsoleNull_Newline() {}
static void __concall ConsoleNull_DoWrite( const wxString& fmt ) {}
static void __concall ConsoleNull_DoWriteLn( const wxString& fmt ) {}
static void __concall ConsoleNull_DoWrite(const wxString &fmt) {}
static void __concall ConsoleNull_DoWriteLn(const wxString &fmt) {}
const IConsoleWriter ConsoleWriter_Null =
{
ConsoleNull_DoWrite,
ConsoleNull_DoWriteLn,
ConsoleNull_DoSetColor,
{
ConsoleNull_DoWrite,
ConsoleNull_DoWriteLn,
ConsoleNull_DoSetColor,
ConsoleNull_DoWrite,
ConsoleNull_Newline,
ConsoleNull_SetTitle,
ConsoleNull_DoWrite,
ConsoleNull_Newline,
ConsoleNull_SetTitle,
0, // instance-level indentation (should always be 0)
0, // instance-level indentation (should always be 0)
};
// --------------------------------------------------------------------------------------
@ -103,118 +103,133 @@ const IConsoleWriter ConsoleWriter_Null =
// --------------------------------------------------------------------------------------
#if defined(__unix__)
static __fi const char* GetLinuxConsoleColor(ConsoleColors color)
static __fi const char *GetLinuxConsoleColor(ConsoleColors color)
{
switch(color)
{
switch (color) {
case Color_Black:
case Color_StrongBlack: return "\033[30m\033[1m";
case Color_StrongBlack:
return "\033[30m\033[1m";
case Color_Red: return "\033[31m";
case Color_StrongRed: return "\033[31m\033[1m";
case Color_Red:
return "\033[31m";
case Color_StrongRed:
return "\033[31m\033[1m";
case Color_Green: return "\033[32m";
case Color_StrongGreen: return "\033[32m\033[1m";
case Color_Green:
return "\033[32m";
case Color_StrongGreen:
return "\033[32m\033[1m";
case Color_Yellow: return "\033[33m";
case Color_StrongYellow: return "\033[33m\033[1m";
case Color_Yellow:
return "\033[33m";
case Color_StrongYellow:
return "\033[33m\033[1m";
case Color_Blue: return "\033[34m";
case Color_StrongBlue: return "\033[34m\033[1m";
case Color_Blue:
return "\033[34m";
case Color_StrongBlue:
return "\033[34m\033[1m";
// No orange, so use magenta.
case Color_Orange:
case Color_Magenta: return "\033[35m";
case Color_Magenta:
return "\033[35m";
case Color_StrongOrange:
case Color_StrongMagenta: return "\033[35m\033[1m";
case Color_StrongMagenta:
return "\033[35m\033[1m";
case Color_Cyan: return "\033[36m";
case Color_StrongCyan: return "\033[36m\033[1m";
case Color_Cyan:
return "\033[36m";
case Color_StrongCyan:
return "\033[36m\033[1m";
// Use 'white' instead of grey.
case Color_Gray:
case Color_White: return "\033[37m";
case Color_White:
return "\033[37m";
case Color_StrongGray:
case Color_StrongWhite: return "\033[37m\033[1m";
case Color_StrongWhite:
return "\033[37m\033[1m";
// On some other value being passed, clear any formatting.
case Color_Default:
default: return "\033[0m";
default:
return "\033[0m";
}
}
#endif
// One possible default write action at startup and shutdown is to use the stdout.
static void __concall ConsoleStdout_DoWrite( const wxString& fmt )
static void __concall ConsoleStdout_DoWrite(const wxString &fmt)
{
MSW_OutputDebugString( fmt );
MSW_OutputDebugString(fmt);
}
// Default write action at startup and shutdown is to use the stdout.
static void __concall ConsoleStdout_DoWriteLn( const wxString& fmt )
static void __concall ConsoleStdout_DoWriteLn(const wxString &fmt)
{
MSW_OutputDebugString( fmt + L"\n" );
MSW_OutputDebugString(fmt + L"\n");
}
static void __concall ConsoleStdout_Newline()
{
MSW_OutputDebugString( L"\n" );
MSW_OutputDebugString(L"\n");
}
static void __concall ConsoleStdout_DoSetColor( ConsoleColors color )
static void __concall ConsoleStdout_DoSetColor(ConsoleColors color)
{
#if defined(__unix__)
fprintf(stdout_fp, "\033[0m%s", GetLinuxConsoleColor(color));
fflush(stdout_fp);
fprintf(stdout_fp, "\033[0m%s", GetLinuxConsoleColor(color));
fflush(stdout_fp);
#endif
}
static void __concall ConsoleStdout_SetTitle( const wxString& title )
static void __concall ConsoleStdout_SetTitle(const wxString &title)
{
#if defined(__unix__)
fputs("\033]0;", stdout_fp);
fputs(title.utf8_str(), stdout_fp);
fputs("\007", stdout_fp);
fputs("\033]0;", stdout_fp);
fputs(title.utf8_str(), stdout_fp);
fputs("\007", stdout_fp);
#endif
}
const IConsoleWriter ConsoleWriter_Stdout =
{
ConsoleStdout_DoWrite, // Writes without newlines go to buffer to avoid error log spam.
ConsoleStdout_DoWriteLn,
ConsoleStdout_DoSetColor,
{
ConsoleStdout_DoWrite, // Writes without newlines go to buffer to avoid error log spam.
ConsoleStdout_DoWriteLn,
ConsoleStdout_DoSetColor,
ConsoleNull_DoWrite, // writes from re-piped stdout are ignored here, lest we create infinite loop hell >_<
ConsoleStdout_Newline,
ConsoleStdout_SetTitle,
0, // instance-level indentation (should always be 0)
ConsoleNull_DoWrite, // writes from re-piped stdout are ignored here, lest we create infinite loop hell >_<
ConsoleStdout_Newline,
ConsoleStdout_SetTitle,
0, // instance-level indentation (should always be 0)
};
// --------------------------------------------------------------------------------------
// ConsoleAssert
// --------------------------------------------------------------------------------------
static void __concall ConsoleAssert_DoWrite( const wxString& fmt )
static void __concall ConsoleAssert_DoWrite(const wxString &fmt)
{
pxFail( L"Console class has not been initialized; Message written:\n\t" + fmt );
pxFail(L"Console class has not been initialized; Message written:\n\t" + fmt);
}
static void __concall ConsoleAssert_DoWriteLn( const wxString& fmt )
static void __concall ConsoleAssert_DoWriteLn(const wxString &fmt)
{
pxFail( L"Console class has not been initialized; Message written:\n\t" + fmt );
pxFail(L"Console class has not been initialized; Message written:\n\t" + fmt);
}
const IConsoleWriter ConsoleWriter_Assert =
{
ConsoleAssert_DoWrite,
ConsoleAssert_DoWriteLn,
ConsoleNull_DoSetColor,
{
ConsoleAssert_DoWrite,
ConsoleAssert_DoWriteLn,
ConsoleNull_DoSetColor,
ConsoleNull_DoWrite,
ConsoleNull_Newline,
ConsoleNull_SetTitle,
ConsoleNull_DoWrite,
ConsoleNull_Newline,
ConsoleNull_SetTitle,
0, // instance-level indentation (should always be 0)
0, // instance-level indentation (should always be 0)
};
// =====================================================================================================
@ -227,214 +242,216 @@ const IConsoleWriter ConsoleWriter_Assert =
// glob_indent - this parameter is used to specify a global indentation setting. It is used by
// WriteLn function, but defaults to 0 for Warning and Error calls. Local indentation always
// applies to all writes.
wxString IConsoleWriter::_addIndentation( const wxString& src, int glob_indent=0 ) const
wxString IConsoleWriter::_addIndentation(const wxString &src, int glob_indent = 0) const
{
const int indent = glob_indent + _imm_indentation;
if( indent == 0 ) return src;
const int indent = glob_indent + _imm_indentation;
if (indent == 0)
return src;
wxString result( src );
const wxString indentStr( L'\t', indent );
result.Replace( L"\n", L"\n" + indentStr );
return indentStr + result;
wxString result(src);
const wxString indentStr(L'\t', indent);
result.Replace(L"\n", L"\n" + indentStr);
return indentStr + result;
}
// Sets the indentation to be applied to all WriteLn's. The indentation is added to the
// primary write, and to any newlines specified within the write. Note that this applies
// to calls to WriteLn *only* -- calls to Write bypass the indentation parser.
const IConsoleWriter& IConsoleWriter::SetIndent( int tabcount ) const
const IConsoleWriter &IConsoleWriter::SetIndent(int tabcount) const
{
conlog_Indent += tabcount;
pxAssert( conlog_Indent >= 0 );
return *this;
conlog_Indent += tabcount;
pxAssert(conlog_Indent >= 0);
return *this;
}
IConsoleWriter IConsoleWriter::Indent( int tabcount ) const
IConsoleWriter IConsoleWriter::Indent(int tabcount) const
{
IConsoleWriter retval = *this;
retval._imm_indentation = tabcount;
return retval;
IConsoleWriter retval = *this;
retval._imm_indentation = tabcount;
return retval;
}
// Changes the active console color.
// This color will be unset by calls to colored text methods
// such as ErrorMsg and Notice.
const IConsoleWriter& IConsoleWriter::SetColor( ConsoleColors color ) const
const IConsoleWriter &IConsoleWriter::SetColor(ConsoleColors color) const
{
// Ignore current color requests since, well, the current color is already set. ;)
if( color == Color_Current ) return *this;
// Ignore current color requests since, well, the current color is already set. ;)
if (color == Color_Current)
return *this;
pxAssertMsg( (color > Color_Current) && (color < ConsoleColors_Count), "Invalid ConsoleColor specified." );
pxAssertMsg((color > Color_Current) && (color < ConsoleColors_Count), "Invalid ConsoleColor specified.");
if( conlog_Color != color )
DoSetColor( conlog_Color = color );
if (conlog_Color != color)
DoSetColor(conlog_Color = color);
return *this;
return *this;
}
ConsoleColors IConsoleWriter::GetColor() const
{
return conlog_Color;
return conlog_Color;
}
// Restores the console color to default (usually black, or low-intensity white if the console uses a black background)
const IConsoleWriter& IConsoleWriter::ClearColor() const
const IConsoleWriter &IConsoleWriter::ClearColor() const
{
if( conlog_Color != DefaultConsoleColor )
DoSetColor( conlog_Color = DefaultConsoleColor );
if (conlog_Color != DefaultConsoleColor)
DoSetColor(conlog_Color = DefaultConsoleColor);
return *this;
return *this;
}
// --------------------------------------------------------------------------------------
// ASCII/UTF8 (char*)
// --------------------------------------------------------------------------------------
bool IConsoleWriter::FormatV( const char* fmt, va_list args ) const
bool IConsoleWriter::FormatV(const char *fmt, va_list args) const
{
DoWriteLn( _addIndentation( pxsFmtV(fmt,args), conlog_Indent ) );
return false;
DoWriteLn(_addIndentation(pxsFmtV(fmt, args), conlog_Indent));
return false;
}
bool IConsoleWriter::WriteLn( const char* fmt, ... ) const
bool IConsoleWriter::WriteLn(const char *fmt, ...) const
{
va_list args;
va_start(args,fmt);
FormatV(fmt, args);
va_end(args);
va_list args;
va_start(args, fmt);
FormatV(fmt, args);
va_end(args);
return false;
return false;
}
bool IConsoleWriter::WriteLn( ConsoleColors color, const char* fmt, ... ) const
bool IConsoleWriter::WriteLn(ConsoleColors color, const char *fmt, ...) const
{
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( color );
FormatV(fmt, args);
va_end(args);
va_list args;
va_start(args, fmt);
ConsoleColorScope cs(color);
FormatV(fmt, args);
va_end(args);
return false;
return false;
}
bool IConsoleWriter::Error( const char* fmt, ... ) const
bool IConsoleWriter::Error(const char *fmt, ...) const
{
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( Color_StrongRed );
FormatV(fmt, args);
va_end(args);
va_list args;
va_start(args, fmt);
ConsoleColorScope cs(Color_StrongRed);
FormatV(fmt, args);
va_end(args);
return false;
return false;
}
bool IConsoleWriter::Warning( const char* fmt, ... ) const
bool IConsoleWriter::Warning(const char *fmt, ...) const
{
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( Color_StrongOrange );
FormatV(fmt, args);
va_end(args);
va_list args;
va_start(args, fmt);
ConsoleColorScope cs(Color_StrongOrange);
FormatV(fmt, args);
va_end(args);
return false;
return false;
}
// --------------------------------------------------------------------------------------
// Write Variants - Unicode/UTF16 style
// --------------------------------------------------------------------------------------
bool IConsoleWriter::FormatV( const wxChar* fmt, va_list args ) const
bool IConsoleWriter::FormatV(const wxChar *fmt, va_list args) const
{
DoWriteLn( _addIndentation( pxsFmtV( fmt, args ), conlog_Indent ) );
return false;
DoWriteLn(_addIndentation(pxsFmtV(fmt, args), conlog_Indent));
return false;
}
bool IConsoleWriter::WriteLn( const wxChar* fmt, ... ) const
bool IConsoleWriter::WriteLn(const wxChar *fmt, ...) const
{
va_list args;
va_start(args,fmt);
FormatV(fmt,args);
va_end(args);
va_list args;
va_start(args, fmt);
FormatV(fmt, args);
va_end(args);
return false;
return false;
}
bool IConsoleWriter::WriteLn( ConsoleColors color, const wxChar* fmt, ... ) const
bool IConsoleWriter::WriteLn(ConsoleColors color, const wxChar *fmt, ...) const
{
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( color );
FormatV(fmt,args);
va_end(args);
va_list args;
va_start(args, fmt);
ConsoleColorScope cs(color);
FormatV(fmt, args);
va_end(args);
return false;
return false;
}
bool IConsoleWriter::Error( const wxChar* fmt, ... ) const
bool IConsoleWriter::Error(const wxChar *fmt, ...) const
{
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( Color_StrongRed );
FormatV(fmt,args);
va_end(args);
va_list args;
va_start(args, fmt);
ConsoleColorScope cs(Color_StrongRed);
FormatV(fmt, args);
va_end(args);
return false;
return false;
}
bool IConsoleWriter::Warning( const wxChar* fmt, ... ) const
bool IConsoleWriter::Warning(const wxChar *fmt, ...) const
{
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( Color_StrongOrange );
FormatV(fmt,args);
va_end(args);
va_list args;
va_start(args, fmt);
ConsoleColorScope cs(Color_StrongOrange);
FormatV(fmt, args);
va_end(args);
return false;
return false;
}
// --------------------------------------------------------------------------------------
// Write Variants - Unknown style
// --------------------------------------------------------------------------------------
bool IConsoleWriter::WriteLn( const wxString fmt, ... ) const
bool IConsoleWriter::WriteLn(const wxString fmt, ...) const
{
va_list args;
va_start(args,fmt);
FormatV(fmt.wx_str(),args);
va_end(args);
va_list args;
va_start(args, fmt);
FormatV(fmt.wx_str(), args);
va_end(args);
return false;
return false;
}
bool IConsoleWriter::WriteLn( ConsoleColors color, const wxString fmt, ... ) const
bool IConsoleWriter::WriteLn(ConsoleColors color, const wxString fmt, ...) const
{
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( color );
FormatV(fmt.wx_str(),args);
va_end(args);
va_list args;
va_start(args, fmt);
ConsoleColorScope cs(color);
FormatV(fmt.wx_str(), args);
va_end(args);
return false;
return false;
}
bool IConsoleWriter::Error( const wxString fmt, ... ) const
bool IConsoleWriter::Error(const wxString fmt, ...) const
{
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( Color_StrongRed );
FormatV(fmt.wx_str(),args);
va_end(args);
va_list args;
va_start(args, fmt);
ConsoleColorScope cs(Color_StrongRed);
FormatV(fmt.wx_str(), args);
va_end(args);
return false;
return false;
}
bool IConsoleWriter::Warning( const wxString fmt, ... ) const
bool IConsoleWriter::Warning(const wxString fmt, ...) const
{
va_list args;
va_start(args,fmt);
ConsoleColorScope cs( Color_StrongOrange );
FormatV(fmt.wx_str(),args);
va_end(args);
va_list args;
va_start(args, fmt);
ConsoleColorScope cs(Color_StrongOrange);
FormatV(fmt.wx_str(), args);
va_end(args);
return false;
return false;
}
@ -442,73 +459,72 @@ bool IConsoleWriter::Warning( const wxString fmt, ... ) const
// ConsoleColorScope / ConsoleIndentScope
// --------------------------------------------------------------------------------------
ConsoleColorScope::ConsoleColorScope( ConsoleColors newcolor )
ConsoleColorScope::ConsoleColorScope(ConsoleColors newcolor)
{
m_IsScoped = false;
m_newcolor = newcolor;
EnterScope();
m_IsScoped = false;
m_newcolor = newcolor;
EnterScope();
}
ConsoleColorScope::~ConsoleColorScope() throw()
{
LeaveScope();
LeaveScope();
}
void ConsoleColorScope::EnterScope()
{
if (!m_IsScoped)
{
m_old_color = Console.GetColor();
Console.SetColor( m_newcolor );
m_IsScoped = true;
}
if (!m_IsScoped) {
m_old_color = Console.GetColor();
Console.SetColor(m_newcolor);
m_IsScoped = true;
}
}
void ConsoleColorScope::LeaveScope()
{
m_IsScoped = m_IsScoped && (Console.SetColor( m_old_color ), false);
m_IsScoped = m_IsScoped && (Console.SetColor(m_old_color), false);
}
ConsoleIndentScope::ConsoleIndentScope( int tabs )
ConsoleIndentScope::ConsoleIndentScope(int tabs)
{
m_IsScoped = false;
m_amount = tabs;
EnterScope();
m_IsScoped = false;
m_amount = tabs;
EnterScope();
}
ConsoleIndentScope::~ConsoleIndentScope() throw()
{
try {
LeaveScope();
}
DESTRUCTOR_CATCHALL
try {
LeaveScope();
}
DESTRUCTOR_CATCHALL
}
void ConsoleIndentScope::EnterScope()
{
m_IsScoped = m_IsScoped || (Console.SetIndent( m_amount ),true);
m_IsScoped = m_IsScoped || (Console.SetIndent(m_amount), true);
}
void ConsoleIndentScope::LeaveScope()
{
m_IsScoped = m_IsScoped && (Console.SetIndent( -m_amount ),false);
m_IsScoped = m_IsScoped && (Console.SetIndent(-m_amount), false);
}
ConsoleAttrScope::ConsoleAttrScope( ConsoleColors newcolor, int indent )
ConsoleAttrScope::ConsoleAttrScope(ConsoleColors newcolor, int indent)
{
m_old_color = Console.GetColor();
Console.SetIndent( m_tabsize = indent );
Console.SetColor( newcolor );
m_old_color = Console.GetColor();
Console.SetIndent(m_tabsize = indent);
Console.SetColor(newcolor);
}
ConsoleAttrScope::~ConsoleAttrScope() throw()
{
try {
Console.SetColor( m_old_color );
Console.SetIndent( -m_tabsize );
}
DESTRUCTOR_CATCHALL
try {
Console.SetColor(m_old_color);
Console.SetIndent(-m_tabsize);
}
DESTRUCTOR_CATCHALL
}
@ -520,18 +536,18 @@ ConsoleAttrScope::~ConsoleAttrScope() throw()
// platform specific code). Under windows Stdout will attempt to write to the IDE Debug
// console, if one is available (such as running pcsx2 via MSVC). If not available, then
// the log message will pretty much be lost into the ether.
//
#define _DefaultWriter_ ConsoleWriter_Stdout
//
#define _DefaultWriter_ ConsoleWriter_Stdout
IConsoleWriter Console = _DefaultWriter_;
IConsoleWriter DevConWriter = _DefaultWriter_;
bool DevConWriterEnabled = false;
IConsoleWriter Console = _DefaultWriter_;
IConsoleWriter DevConWriter = _DefaultWriter_;
bool DevConWriterEnabled = false;
#ifdef PCSX2_DEBUG
IConsoleWriter DbgConWriter = _DefaultWriter_;
IConsoleWriter DbgConWriter = _DefaultWriter_;
#endif
NullConsoleWriter NullCon = {};
NullConsoleWriter NullCon = {};
// --------------------------------------------------------------------------------------
// ConsoleLogSource (implementations)
@ -539,31 +555,31 @@ NullConsoleWriter NullCon = {};
// Writes to the console using the specified color. This overrides the default color setting
// for this log.
bool ConsoleLogSource::WriteV( ConsoleColors color, const char *fmt, va_list list ) const
bool ConsoleLogSource::WriteV(ConsoleColors color, const char *fmt, va_list list) const
{
ConsoleColorScope cs(color);
DoWrite( pxsFmtV(fmt,list).c_str() );
return false;
ConsoleColorScope cs(color);
DoWrite(pxsFmtV(fmt, list).c_str());
return false;
}
bool ConsoleLogSource::WriteV( ConsoleColors color, const wxChar *fmt, va_list list ) const
bool ConsoleLogSource::WriteV(ConsoleColors color, const wxChar *fmt, va_list list) const
{
ConsoleColorScope cs(color);
DoWrite( pxsFmtV(fmt,list).c_str() );
return false;
ConsoleColorScope cs(color);
DoWrite(pxsFmtV(fmt, list).c_str());
return false;
}
// Writes to the console using the source's default color. Note that the source's default
// color will always be used, thus ConsoleColorScope() will not be effectual unless the
// console's default color is Color_Default.
bool ConsoleLogSource::WriteV( const char *fmt, va_list list ) const
bool ConsoleLogSource::WriteV(const char *fmt, va_list list) const
{
WriteV( DefaultColor, fmt, list );
return false;
WriteV(DefaultColor, fmt, list);
return false;
}
bool ConsoleLogSource::WriteV( const wxChar *fmt, va_list list ) const
bool ConsoleLogSource::WriteV(const wxChar *fmt, va_list list) const
{
WriteV( DefaultColor, fmt, list );
return false;
WriteV(DefaultColor, fmt, list);
return false;
}

View File

@ -24,7 +24,7 @@
#include <mach/mach_time.h>
#define NELEM(x) \
((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
((sizeof(x) / sizeof(0 [x])) / ((size_t)(!(sizeof(x) % sizeof(0 [x])))))
// Darwin (OSX) is a bit different from Linux when requesting properties of
// the OS because of its BSD/Mach heritage. Helpfully, most of this code
@ -38,23 +38,23 @@
// failure (not supported by the operating system).
u64 GetPhysicalMemory()
{
static u64 mem = 0;
static u64 mem = 0;
// fetch the total memory only once, as its an expensive system call and
// doesn't change during the course of the program. Thread-safety is
// ensured by atomic operations with full-barriers (usually compiled
// down to XCHG on x86).
if (__atomic_load_n(&mem, __ATOMIC_SEQ_CST) == 0) {
u64 getmem = 0;
size_t len = sizeof(getmem);
int mib[] = { CTL_HW, HW_MEMSIZE };
if (sysctl(mib, NELEM(mib), &getmem, &len, NULL, 0) < 0) {
perror("sysctl:");
}
__atomic_store_n(&mem, getmem, __ATOMIC_SEQ_CST);
}
// fetch the total memory only once, as its an expensive system call and
// doesn't change during the course of the program. Thread-safety is
// ensured by atomic operations with full-barriers (usually compiled
// down to XCHG on x86).
if (__atomic_load_n(&mem, __ATOMIC_SEQ_CST) == 0) {
u64 getmem = 0;
size_t len = sizeof(getmem);
int mib[] = {CTL_HW, HW_MEMSIZE};
if (sysctl(mib, NELEM(mib), &getmem, &len, NULL, 0) < 0) {
perror("sysctl:");
}
__atomic_store_n(&mem, getmem, __ATOMIC_SEQ_CST);
}
return mem;
return mem;
}
void InitCPUTicks()
@ -71,26 +71,26 @@ void InitCPUTicks()
// GetTickFrequency() to maintain good precision.
u64 GetTickFrequency()
{
static u64 freq = 0;
static u64 freq = 0;
// by the time denom is not 0, the structure will have been fully
// updated and no more atomic accesses are necessary.
if (__atomic_load_n(&freq, __ATOMIC_SEQ_CST) == 0) {
mach_timebase_info_data_t info;
// by the time denom is not 0, the structure will have been fully
// updated and no more atomic accesses are necessary.
if (__atomic_load_n(&freq, __ATOMIC_SEQ_CST) == 0) {
mach_timebase_info_data_t info;
// mach_timebase_info() is a syscall, very slow, that's why we take
// pains to only do it once. On x86(-64), the result is guaranteed
// to be info.denom == info.numer == 1 (i.e.: the frequency is 1e9,
// which means GetCPUTicks is just nanoseconds).
if (mach_timebase_info(&info) != KERN_SUCCESS) {
abort();
}
// mach_timebase_info() is a syscall, very slow, that's why we take
// pains to only do it once. On x86(-64), the result is guaranteed
// to be info.denom == info.numer == 1 (i.e.: the frequency is 1e9,
// which means GetCPUTicks is just nanoseconds).
if (mach_timebase_info(&info) != KERN_SUCCESS) {
abort();
}
// store the calculated value atomically
__atomic_store_n(&freq, (u64) 1e9 * (u64) info.denom / (u64) info.numer, __ATOMIC_SEQ_CST);
}
// store the calculated value atomically
__atomic_store_n(&freq, (u64)1e9 * (u64)info.denom / (u64)info.numer, __ATOMIC_SEQ_CST);
}
return freq;
return freq;
}
// return the number of "ticks" since some arbitrary, fixed time in the
@ -99,52 +99,52 @@ u64 GetTickFrequency()
// nanoseconds.
u64 GetCPUTicks()
{
return mach_absolute_time();
return mach_absolute_time();
}
wxString GetOSVersionString()
{
wxString version;
static int initialized = 0;
wxString version;
static int initialized = 0;
// fetch the OS description only once (thread-safely)
if (__atomic_load_n(&initialized, __ATOMIC_SEQ_CST) == 0) {
char type[32] = {0};
char release[32] = {0};
char arch[32] = {0};
// fetch the OS description only once (thread-safely)
if (__atomic_load_n(&initialized, __ATOMIC_SEQ_CST) == 0) {
char type[32] = {0};
char release[32] = {0};
char arch[32] = {0};
#define SYSCTL_GET(var, base, name) \
do { \
int mib[] = { base, name }; \
size_t len = sizeof(var); \
sysctl(mib, NELEM(mib), NULL, &len, NULL, 0); \
sysctl(mib, NELEM(mib), var, &len, NULL, 0); \
} while (0)
#define SYSCTL_GET(var, base, name) \
do { \
int mib[] = {base, name}; \
size_t len = sizeof(var); \
sysctl(mib, NELEM(mib), NULL, &len, NULL, 0); \
sysctl(mib, NELEM(mib), var, &len, NULL, 0); \
} while (0)
SYSCTL_GET(release, CTL_KERN, KERN_OSRELEASE);
SYSCTL_GET(type, CTL_KERN, KERN_OSTYPE);
SYSCTL_GET(arch, CTL_HW, HW_MACHINE);
SYSCTL_GET(release, CTL_KERN, KERN_OSRELEASE);
SYSCTL_GET(type, CTL_KERN, KERN_OSTYPE);
SYSCTL_GET(arch, CTL_HW, HW_MACHINE);
#undef SYSCTL_KERN
// I know strcat is not good, but stpcpy is not universally
// available yet.
char buf[128] = {0};
strcat(buf, type);
strcat(buf, " ");
strcat(buf, release);
strcat(buf, " ");
strcat(buf, arch);
// I know strcat is not good, but stpcpy is not universally
// available yet.
char buf[128] = {0};
strcat(buf, type);
strcat(buf, " ");
strcat(buf, release);
strcat(buf, " ");
strcat(buf, arch);
version = buf;
version = buf;
__atomic_store_n(&initialized, 1, __ATOMIC_SEQ_CST);
}
__atomic_store_n(&initialized, 1, __ATOMIC_SEQ_CST);
}
return version;
return version;
}
void ScreensaverAllow(bool allow)
{
// no-op
// no-op
}

View File

@ -14,17 +14,17 @@
*/
#include <cstdio>
#include <cassert> // assert
#include <cassert> // assert
#include <pthread.h> // pthread_setcancelstate()
#include <pthread.h> // pthread_setcancelstate()
#include <sys/time.h> // gettimeofday()
#include <sys/time.h> // gettimeofday()
#include <mach/mach.h>
#include <mach/task.h> // semaphore_create() and semaphore_destroy()
#include <mach/semaphore.h> // semaphore_*()
#include <mach/mach_error.h> // mach_error_string()
#include <mach/mach_time.h> // mach_absolute_time()
#include <mach/task.h> // semaphore_create() and semaphore_destroy()
#include <mach/semaphore.h> // semaphore_*()
#include <mach/mach_error.h> // mach_error_string()
#include <mach/mach_time.h> // mach_absolute_time()
#include "PrecompiledHeader.h"
@ -47,105 +47,105 @@
//
// --------------------------------------------------------------------------------------
#define MACH_CHECK(mach_retval) \
do { \
kern_return_t _kr = (mach_retval); \
if (_kr != KERN_SUCCESS) { \
fprintf(stderr, "mach error: %s", mach_error_string(_kr)); \
assert(_kr == KERN_SUCCESS); \
} \
} while (0)
#define MACH_CHECK(mach_retval) \
do { \
kern_return_t _kr = (mach_retval); \
if (_kr != KERN_SUCCESS) { \
fprintf(stderr, "mach error: %s", mach_error_string(_kr)); \
assert(_kr == KERN_SUCCESS); \
} \
} while (0)
Threading::Semaphore::Semaphore()
{
// other platforms explicitly make a thread-private (unshared) semaphore
// here. But it seems Mach doesn't support that.
MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *)&m_sema, SYNC_POLICY_FIFO, 0));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
// other platforms explicitly make a thread-private (unshared) semaphore
// here. But it seems Mach doesn't support that.
MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *)&m_sema, SYNC_POLICY_FIFO, 0));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
}
Threading::Semaphore::~Semaphore() throw()
{
MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t) m_sema));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t)m_sema));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
}
void Threading::Semaphore::Reset()
{
MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t) m_sema));
MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *) &m_sema, SYNC_POLICY_FIFO, 0));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t)m_sema));
MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *)&m_sema, SYNC_POLICY_FIFO, 0));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
}
void Threading::Semaphore::Post()
{
MACH_CHECK(semaphore_signal(m_sema));
__atomic_add_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
MACH_CHECK(semaphore_signal(m_sema));
__atomic_add_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
}
void Threading::Semaphore::Post(int multiple)
{
for (int i = 0; i < multiple; ++i) {
MACH_CHECK(semaphore_signal(m_sema));
}
__atomic_add_fetch(&m_counter, multiple, __ATOMIC_SEQ_CST);
for (int i = 0; i < multiple; ++i) {
MACH_CHECK(semaphore_signal(m_sema));
}
__atomic_add_fetch(&m_counter, multiple, __ATOMIC_SEQ_CST);
}
void Threading::Semaphore::WaitWithoutYield()
{
pxAssertMsg(!wxThread::IsMain(), "Unyielding semaphore wait issued from the main/gui thread. Please use Wait() instead.");
MACH_CHECK(semaphore_wait(m_sema));
__atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
pxAssertMsg(!wxThread::IsMain(), "Unyielding semaphore wait issued from the main/gui thread. Please use Wait() instead.");
MACH_CHECK(semaphore_wait(m_sema));
__atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
}
bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan& timeout)
bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan &timeout)
{
// This method is the reason why there has to be a special Darwin
// implementation of Semaphore. Note that semaphore_timedwait() is prone
// to returning with KERN_ABORTED, which basically signifies that some
// signal has worken it up. The best official "documentation" for
// semaphore_timedwait() is the way it's used in Grand Central Dispatch,
// which is open-source.
// This method is the reason why there has to be a special Darwin
// implementation of Semaphore. Note that semaphore_timedwait() is prone
// to returning with KERN_ABORTED, which basically signifies that some
// signal has worken it up. The best official "documentation" for
// semaphore_timedwait() is the way it's used in Grand Central Dispatch,
// which is open-source.
// on x86 platforms, mach_absolute_time() returns nanoseconds
// TODO(aktau): on iOS a scale value from mach_timebase_info will be necessary
u64 const kOneThousand = 1000;
u64 const kOneBillion = kOneThousand * kOneThousand * kOneThousand;
u64 const delta = timeout.GetMilliseconds().GetValue() * (kOneThousand * kOneThousand);
mach_timespec_t ts;
kern_return_t kr = KERN_ABORTED;
for (u64 now = mach_absolute_time(), deadline = now + delta;
kr == KERN_ABORTED; now = mach_absolute_time()) {
if (now > deadline) {
// timed out by definition
return false;
}
// on x86 platforms, mach_absolute_time() returns nanoseconds
// TODO(aktau): on iOS a scale value from mach_timebase_info will be necessary
u64 const kOneThousand = 1000;
u64 const kOneBillion = kOneThousand * kOneThousand * kOneThousand;
u64 const delta = timeout.GetMilliseconds().GetValue() * (kOneThousand * kOneThousand);
mach_timespec_t ts;
kern_return_t kr = KERN_ABORTED;
for (u64 now = mach_absolute_time(), deadline = now + delta;
kr == KERN_ABORTED; now = mach_absolute_time()) {
if (now > deadline) {
// timed out by definition
return false;
}
u64 timeleft = deadline - now;
ts.tv_sec = timeleft / kOneBillion;
ts.tv_nsec = timeleft % kOneBillion;
u64 timeleft = deadline - now;
ts.tv_sec = timeleft / kOneBillion;
ts.tv_nsec = timeleft % kOneBillion;
// possible return values of semaphore_timedwait() (from XNU sources):
// internal kernel val -> return value
// THREAD_INTERRUPTED -> KERN_ABORTED
// THREAD_TIMED_OUT -> KERN_OPERATION_TIMED_OUT
// THREAD_AWAKENED -> KERN_SUCCESS
// THREAD_RESTART -> KERN_TERMINATED
// default -> KERN_FAILURE
kr = semaphore_timedwait(m_sema, ts);
}
// possible return values of semaphore_timedwait() (from XNU sources):
// internal kernel val -> return value
// THREAD_INTERRUPTED -> KERN_ABORTED
// THREAD_TIMED_OUT -> KERN_OPERATION_TIMED_OUT
// THREAD_AWAKENED -> KERN_SUCCESS
// THREAD_RESTART -> KERN_TERMINATED
// default -> KERN_FAILURE
kr = semaphore_timedwait(m_sema, ts);
}
if (kr == KERN_OPERATION_TIMED_OUT) {
return false;
}
if (kr == KERN_OPERATION_TIMED_OUT) {
return false;
}
// while it's entirely possible to have KERN_FAILURE here, we should
// probably assert so we can study and correct the actual error here
// (the thread dying while someone is wainting for it).
MACH_CHECK(kr);
// while it's entirely possible to have KERN_FAILURE here, we should
// probably assert so we can study and correct the actual error here
// (the thread dying while someone is wainting for it).
MACH_CHECK(kr);
__atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
return true;
__atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
return true;
}
// This is a wxApp-safe implementation of Wait, which makes sure and executes the App's
@ -155,20 +155,18 @@ bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan& timeout)
void Threading::Semaphore::Wait()
{
#if wxUSE_GUI
if(!wxThread::IsMain() || (wxTheApp == NULL)) {
WaitWithoutYield();
}
else if(_WaitGui_RecursionGuard( L"Semaphore::Wait" )) {
ScopedBusyCursor hourglass( Cursor_ReallyBusy );
WaitWithoutYield();
}
else {
while (!WaitWithoutYield(def_yieldgui_interval)) {
YieldToMain();
}
}
if (!wxThread::IsMain() || (wxTheApp == NULL)) {
WaitWithoutYield();
} else if (_WaitGui_RecursionGuard(L"Semaphore::Wait")) {
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
WaitWithoutYield();
} else {
while (!WaitWithoutYield(def_yieldgui_interval)) {
YieldToMain();
}
}
#else
WaitWithoutYield();
WaitWithoutYield();
#endif
}
@ -181,30 +179,29 @@ void Threading::Semaphore::Wait()
// false if the wait timed out before the semaphore was signaled, or true if the signal was
// reached prior to timeout.
//
bool Threading::Semaphore::Wait(const wxTimeSpan& timeout)
bool Threading::Semaphore::Wait(const wxTimeSpan &timeout)
{
#if wxUSE_GUI
if(!wxThread::IsMain() || (wxTheApp == NULL)) {
return WaitWithoutYield(timeout);
}
else if (_WaitGui_RecursionGuard( L"Semaphore::TimedWait")) {
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
return WaitWithoutYield(timeout);
}
else {
//ScopedBusyCursor hourglass( Cursor_KindaBusy );
wxTimeSpan countdown((timeout));
if (!wxThread::IsMain() || (wxTheApp == NULL)) {
return WaitWithoutYield(timeout);
} else if (_WaitGui_RecursionGuard(L"Semaphore::TimedWait")) {
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
return WaitWithoutYield(timeout);
} else {
//ScopedBusyCursor hourglass( Cursor_KindaBusy );
wxTimeSpan countdown((timeout));
do {
if (WaitWithoutYield(def_yieldgui_interval)) break;
YieldToMain();
countdown -= def_yieldgui_interval;
} while (countdown.GetMilliseconds() > 0);
do {
if (WaitWithoutYield(def_yieldgui_interval))
break;
YieldToMain();
countdown -= def_yieldgui_interval;
} while (countdown.GetMilliseconds() > 0);
return countdown.GetMilliseconds() > 0;
}
return countdown.GetMilliseconds() > 0;
}
#else
return WaitWithoutYield(timeout);
return WaitWithoutYield(timeout);
#endif
}
@ -223,21 +220,21 @@ bool Threading::Semaphore::Wait(const wxTimeSpan& timeout)
// POSIX threads), this should work. -- aktau
void Threading::Semaphore::WaitNoCancel()
{
int oldstate;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
Wait();
pthread_setcancelstate(oldstate, NULL);
int oldstate;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
Wait();
pthread_setcancelstate(oldstate, NULL);
}
void Threading::Semaphore::WaitNoCancel(const wxTimeSpan& timeout)
void Threading::Semaphore::WaitNoCancel(const wxTimeSpan &timeout)
{
int oldstate;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
Wait(timeout);
pthread_setcancelstate(oldstate, NULL);
int oldstate;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
Wait(timeout);
pthread_setcancelstate(oldstate, NULL);
}
int Threading::Semaphore::Count()
{
return __atomic_load_n(&m_counter, __ATOMIC_SEQ_CST);
return __atomic_load_n(&m_counter, __ATOMIC_SEQ_CST);
}

View File

@ -19,7 +19,7 @@
#include <unistd.h>
#if !defined(__APPLE__)
# error "DarwinThreads.cpp should only be compiled by projects or makefiles targeted at OSX."
#error "DarwinThreads.cpp should only be compiled by projects or makefiles targeted at OSX."
#else
#include <mach/mach_init.h>
@ -30,7 +30,7 @@
// the LOCK prefix. The prefix works on single core CPUs fine (but is slow), but not
// having the LOCK prefix is very bad indeed.
__forceinline void Threading::Sleep( int ms )
__forceinline void Threading::Sleep(int ms)
{
usleep(1000 * ms);
}
@ -41,7 +41,7 @@ __forceinline void Threading::SpinWait()
{
// If this doesn't compile you can just comment it out (it only serves as a
// performance hint and isn't required).
__asm__ ( "pause" );
__asm__("pause");
}
__forceinline void Threading::EnableHiresScheduler()
@ -66,21 +66,22 @@ u64 Threading::GetThreadTicksPerSecond()
// gets the CPU time used by the current thread (both system and user), in
// microseconds, returns 0 on failure
static u64 getthreadtime(thread_port_t thread) {
static u64 getthreadtime(thread_port_t thread)
{
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
thread_basic_info_data_t info;
kern_return_t kr = thread_info(thread, THREAD_BASIC_INFO,
(thread_info_t) &info, &count);
(thread_info_t)&info, &count);
if (kr != KERN_SUCCESS) {
return 0;
}
// add system and user time
return (u64) info.user_time.seconds * (u64) 1e6 +
(u64) info.user_time.microseconds +
(u64) info.system_time.seconds * (u64) 1e6 +
(u64) info.system_time.microseconds;
return (u64)info.user_time.seconds * (u64)1e6 +
(u64)info.user_time.microseconds +
(u64)info.system_time.seconds * (u64)1e6 +
(u64)info.system_time.microseconds;
}
// Returns the current timestamp (not relative to a real world clock) in
@ -109,19 +110,19 @@ u64 Threading::pxThread::GetCpuTime() const
return 0;
}
return getthreadtime((thread_port_t) m_native_id) * 10ULL;
return getthreadtime((thread_port_t)m_native_id) * 10ULL;
}
void Threading::pxThread::_platform_specific_OnStartInThread()
{
m_native_id = (uptr) mach_thread_self();
m_native_id = (uptr)mach_thread_self();
}
void Threading::pxThread::_platform_specific_OnCleanupInThread()
{
// cleanup of handles that were upened in
// _platform_specific_OnStartInThread
mach_port_deallocate(mach_task_self(), (thread_port_t) m_native_id);
mach_port_deallocate(mach_task_self(), (thread_port_t)m_native_id);
}
// name can be up to 16 bytes

View File

@ -43,37 +43,37 @@ Fnptr_OutOfMemory pxDoOutOfMemory = NULL;
// const false).
//
#ifdef PCSX2_DEVBUILD
# define DEVASSERT_INLINE __noinline
#define DEVASSERT_INLINE __noinline
#else
# define DEVASSERT_INLINE __fi
#define DEVASSERT_INLINE __fi
#endif
// Using a threadlocal assertion guard. Separate threads can assert at the same time.
// That's ok. What we don't want is the *same* thread recurse-asserting.
static DeclareTls(int) s_assert_guard( 0 );
static DeclareTls(int) s_assert_guard(0);
pxDoAssertFnType* pxDoAssert = pxAssertImpl_LogIt;
pxDoAssertFnType *pxDoAssert = pxAssertImpl_LogIt;
// make life easier for people using VC++ IDE by using this format, which allows double-click
// response times from the Output window...
wxString DiagnosticOrigin::ToString( const wxChar* msg ) const
wxString DiagnosticOrigin::ToString(const wxChar *msg) const
{
FastFormatUnicode message;
FastFormatUnicode message;
message.Write( L"%ls(%d) : assertion failed:\n", srcfile, line );
message.Write(L"%ls(%d) : assertion failed:\n", srcfile, line);
if( function != NULL )
message.Write( " Function: %s\n", function );
if (function != NULL)
message.Write(" Function: %s\n", function);
message.Write(L" Thread: %s\n", WX_STR(Threading::pxGetCurrentThreadName()) );
message.Write(L" Thread: %s\n", WX_STR(Threading::pxGetCurrentThreadName()));
if( condition != NULL )
message.Write(L" Condition: %ls\n", condition);
if (condition != NULL)
message.Write(L" Condition: %ls\n", condition);
if( msg != NULL )
message.Write(L" Message: %ls\n", msg);
if (msg != NULL)
message.Write(L" Message: %ls\n", msg);
return message;
return message;
}
@ -83,71 +83,72 @@ void pxTrap()
#if defined(__WXMSW__) && !defined(__WXMICROWIN__)
__debugbreak();
#elif defined(__WXMAC__) && !defined(__DARWIN__)
#if __powerc
Debugger();
#else
SysBreak();
#endif
#if __powerc
Debugger();
#else
SysBreak();
#endif
#elif defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
Debugger();
#elif defined(__UNIX__)
raise(SIGTRAP);
#else
// TODO
// TODO
#endif // Win/Unix
}
bool pxAssertImpl_LogIt( const DiagnosticOrigin& origin, const wxChar *msg )
bool pxAssertImpl_LogIt(const DiagnosticOrigin &origin, const wxChar *msg)
{
//wxLogError( L"%s", origin.ToString( msg ).c_str() );
wxMessageOutputDebug().Printf( L"%s", origin.ToString( msg ).c_str() );
pxTrap();
return false;
//wxLogError( L"%s", origin.ToString( msg ).c_str() );
wxMessageOutputDebug().Printf(L"%s", origin.ToString(msg).c_str());
pxTrap();
return false;
}
DEVASSERT_INLINE void pxOnAssert( const DiagnosticOrigin& origin, const wxChar* msg )
DEVASSERT_INLINE void pxOnAssert(const DiagnosticOrigin &origin, const wxChar *msg)
{
// Recursion guard: Allow at least one recursive call. This is useful because sometimes
// we get meaningless assertions while unwinding stack traces after exceptions have occurred.
// Recursion guard: Allow at least one recursive call. This is useful because sometimes
// we get meaningless assertions while unwinding stack traces after exceptions have occurred.
RecursionGuard guard( s_assert_guard );
if (guard.Counter > 2) { return pxTrap(); }
RecursionGuard guard(s_assert_guard);
if (guard.Counter > 2) {
return pxTrap();
}
// wxWidgets doesn't come with debug builds on some Linux distros, and other distros make
// it difficult to use the debug build (compilation failures). To handle these I've had to
// bypass the internal wxWidgets assertion handler entirely, since it may not exist even if
// PCSX2 itself is compiled in debug mode (assertions enabled).
// wxWidgets doesn't come with debug builds on some Linux distros, and other distros make
// it difficult to use the debug build (compilation failures). To handle these I've had to
// bypass the internal wxWidgets assertion handler entirely, since it may not exist even if
// PCSX2 itself is compiled in debug mode (assertions enabled).
bool trapit;
bool trapit;
if( pxDoAssert == NULL )
{
// Note: Format uses MSVC's syntax for output window hotlinking.
trapit = pxAssertImpl_LogIt( origin, msg );
}
else
{
trapit = pxDoAssert( origin, msg );
}
if (pxDoAssert == NULL) {
// Note: Format uses MSVC's syntax for output window hotlinking.
trapit = pxAssertImpl_LogIt(origin, msg);
} else {
trapit = pxDoAssert(origin, msg);
}
if( trapit ) { pxTrap(); }
if (trapit) {
pxTrap();
}
}
__fi void pxOnAssert( const DiagnosticOrigin& origin, const char* msg)
__fi void pxOnAssert(const DiagnosticOrigin &origin, const char *msg)
{
pxOnAssert( origin, fromUTF8(msg) );
pxOnAssert(origin, fromUTF8(msg));
}
__fi void pxOnAssert( const DiagnosticOrigin& origin, const wxString& msg)
__fi void pxOnAssert(const DiagnosticOrigin &origin, const wxString &msg)
{
pxOnAssert( origin, msg.wc_str() );
pxOnAssert(origin, msg.wc_str());
}
__fi void pxOnAssert( const DiagnosticOrigin& origin, const FastFormatUnicode& msg)
__fi void pxOnAssert(const DiagnosticOrigin &origin, const FastFormatUnicode &msg)
{
pxOnAssert( origin, msg.c_str());
pxOnAssert(origin, msg.c_str());
}
// --------------------------------------------------------------------------------------
@ -156,136 +157,132 @@ __fi void pxOnAssert( const DiagnosticOrigin& origin, const FastFormatUnicode& m
BaseException::~BaseException() throw() {}
BaseException& BaseException::SetBothMsgs( const wxChar* msg_diag )
BaseException &BaseException::SetBothMsgs(const wxChar *msg_diag)
{
m_message_user = msg_diag ? wxString(wxGetTranslation( msg_diag )) : wxString("");
return SetDiagMsg( msg_diag );
m_message_user = msg_diag ? wxString(wxGetTranslation(msg_diag)) : wxString("");
return SetDiagMsg(msg_diag);
}
BaseException& BaseException::SetDiagMsg( const wxString& msg_diag )
BaseException &BaseException::SetDiagMsg(const wxString &msg_diag)
{
m_message_diag = msg_diag;
return *this;
m_message_diag = msg_diag;
return *this;
}
BaseException& BaseException::SetUserMsg( const wxString& msg_user )
BaseException &BaseException::SetUserMsg(const wxString &msg_user)
{
m_message_user = msg_user;
return *this;
m_message_user = msg_user;
return *this;
}
wxString BaseException::FormatDiagnosticMessage() const
{
return m_message_diag;
return m_message_diag;
}
wxString BaseException::FormatDisplayMessage() const
{
return m_message_user.IsEmpty() ? m_message_diag : m_message_user;
return m_message_user.IsEmpty() ? m_message_diag : m_message_user;
}
// --------------------------------------------------------------------------------------
// Exception::RuntimeError (implementations)
// --------------------------------------------------------------------------------------
Exception::RuntimeError::RuntimeError( const std::runtime_error& ex, const wxString& prefix )
Exception::RuntimeError::RuntimeError(const std::runtime_error &ex, const wxString &prefix)
{
IsSilent = false;
IsSilent = false;
SetDiagMsg( pxsFmt( L"STL Runtime Error%s: %s",
(prefix.IsEmpty() ? L"" : pxsFmt(L" (%s)", WX_STR(prefix)).c_str()),
WX_STR(fromUTF8( ex.what() ))
) );
SetDiagMsg(pxsFmt(L"STL Runtime Error%s: %s",
(prefix.IsEmpty() ? L"" : pxsFmt(L" (%s)", WX_STR(prefix)).c_str()),
WX_STR(fromUTF8(ex.what()))));
}
Exception::RuntimeError::RuntimeError( const std::exception& ex, const wxString& prefix )
Exception::RuntimeError::RuntimeError(const std::exception &ex, const wxString &prefix)
{
IsSilent = false;
IsSilent = false;
SetDiagMsg( pxsFmt( L"STL Exception%s: %s",
(prefix.IsEmpty() ? L"" : pxsFmt(L" (%s)", WX_STR(prefix)).c_str()),
WX_STR(fromUTF8( ex.what() ))
) );
SetDiagMsg(pxsFmt(L"STL Exception%s: %s",
(prefix.IsEmpty() ? L"" : pxsFmt(L" (%s)", WX_STR(prefix)).c_str()),
WX_STR(fromUTF8(ex.what()))));
}
// --------------------------------------------------------------------------------------
// Exception::OutOfMemory (implementations)
// --------------------------------------------------------------------------------------
Exception::OutOfMemory::OutOfMemory( const wxString& allocdesc )
Exception::OutOfMemory::OutOfMemory(const wxString &allocdesc)
{
AllocDescription = allocdesc;
AllocDescription = allocdesc;
}
wxString Exception::OutOfMemory::FormatDiagnosticMessage() const
{
FastFormatUnicode retmsg;
retmsg.Write(L"Out of memory");
if (!AllocDescription.IsEmpty())
retmsg.Write(L" while allocating '%s'", WX_STR(AllocDescription));
FastFormatUnicode retmsg;
retmsg.Write(L"Out of memory");
if (!AllocDescription.IsEmpty())
retmsg.Write(L" while allocating '%s'", WX_STR(AllocDescription));
if (!m_message_diag.IsEmpty())
retmsg.Write(L":\n%s", WX_STR(m_message_diag));
return retmsg;
if (!m_message_diag.IsEmpty())
retmsg.Write(L":\n%s", WX_STR(m_message_diag));
return retmsg;
}
wxString Exception::OutOfMemory::FormatDisplayMessage() const
{
FastFormatUnicode retmsg;
retmsg.Write( L"%s", _("Oh noes! Out of memory!") );
FastFormatUnicode retmsg;
retmsg.Write(L"%s", _("Oh noes! Out of memory!"));
if (!m_message_user.IsEmpty())
retmsg.Write(L"\n\n%s", WX_STR(m_message_user));
if (!m_message_user.IsEmpty())
retmsg.Write(L"\n\n%s", WX_STR(m_message_user));
return retmsg;
return retmsg;
}
// --------------------------------------------------------------------------------------
// Exception::VirtualMemoryMapConflict (implementations)
// --------------------------------------------------------------------------------------
Exception::VirtualMemoryMapConflict::VirtualMemoryMapConflict( const wxString& allocdesc )
Exception::VirtualMemoryMapConflict::VirtualMemoryMapConflict(const wxString &allocdesc)
{
AllocDescription = allocdesc;
m_message_user = _("Virtual memory mapping failure! Your system may have conflicting device drivers, services, or may simply have insufficient memory or resources to meet PCSX2's lofty needs.");
AllocDescription = allocdesc;
m_message_user = _("Virtual memory mapping failure! Your system may have conflicting device drivers, services, or may simply have insufficient memory or resources to meet PCSX2's lofty needs.");
}
wxString Exception::VirtualMemoryMapConflict::FormatDiagnosticMessage() const
{
FastFormatUnicode retmsg;
retmsg.Write(L"Virtual memory map failed");
if (!AllocDescription.IsEmpty())
retmsg.Write(L" while reserving '%s'", WX_STR(AllocDescription));
FastFormatUnicode retmsg;
retmsg.Write(L"Virtual memory map failed");
if (!AllocDescription.IsEmpty())
retmsg.Write(L" while reserving '%s'", WX_STR(AllocDescription));
if (!m_message_diag.IsEmpty())
retmsg.Write(L":\n%s", WX_STR(m_message_diag));
return retmsg;
if (!m_message_diag.IsEmpty())
retmsg.Write(L":\n%s", WX_STR(m_message_diag));
return retmsg;
}
wxString Exception::VirtualMemoryMapConflict::FormatDisplayMessage() const
{
FastFormatUnicode retmsg;
retmsg.Write( L"%s",
pxE( L"There is not enough virtual memory available, or necessary virtual memory mappings have already been reserved by other processes, services, or DLLs."
)
);
FastFormatUnicode retmsg;
retmsg.Write(L"%s",
pxE(L"There is not enough virtual memory available, or necessary virtual memory mappings have already been reserved by other processes, services, or DLLs."));
if (!m_message_diag.IsEmpty())
retmsg.Write(L"\n\n%s", WX_STR(m_message_diag));
if (!m_message_diag.IsEmpty())
retmsg.Write(L"\n\n%s", WX_STR(m_message_diag));
return retmsg;
return retmsg;
}
// ------------------------------------------------------------------------
wxString Exception::CancelEvent::FormatDiagnosticMessage() const
{
return L"Action canceled: " + m_message_diag;
return L"Action canceled: " + m_message_diag;
}
wxString Exception::CancelEvent::FormatDisplayMessage() const
{
return L"Action canceled: " + m_message_diag;
return L"Action canceled: " + m_message_diag;
}
// --------------------------------------------------------------------------------------
@ -293,40 +290,40 @@ wxString Exception::CancelEvent::FormatDisplayMessage() const
// --------------------------------------------------------------------------------------
wxString Exception::BadStream::FormatDiagnosticMessage() const
{
FastFormatUnicode retval;
_formatDiagMsg(retval);
return retval;
FastFormatUnicode retval;
_formatDiagMsg(retval);
return retval;
}
wxString Exception::BadStream::FormatDisplayMessage() const
{
FastFormatUnicode retval;
_formatUserMsg(retval);
return retval;
FastFormatUnicode retval;
_formatUserMsg(retval);
return retval;
}
void Exception::BadStream::_formatDiagMsg( FastFormatUnicode& dest ) const
void Exception::BadStream::_formatDiagMsg(FastFormatUnicode &dest) const
{
dest.Write( L"Path: " );
if (!StreamName.IsEmpty())
dest.Write( L"%s", WX_STR(StreamName) );
else
dest.Write( L"[Unnamed or unknown]" );
dest.Write(L"Path: ");
if (!StreamName.IsEmpty())
dest.Write(L"%s", WX_STR(StreamName));
else
dest.Write(L"[Unnamed or unknown]");
if (!m_message_diag.IsEmpty())
dest.Write(L"\n%s", WX_STR(m_message_diag));
if (!m_message_diag.IsEmpty())
dest.Write(L"\n%s", WX_STR(m_message_diag));
}
void Exception::BadStream::_formatUserMsg( FastFormatUnicode& dest ) const
void Exception::BadStream::_formatUserMsg(FastFormatUnicode &dest) const
{
dest.Write( _("Path: ") );
if (!StreamName.IsEmpty())
dest.Write( L"%s", WX_STR(StreamName) );
else
dest.Write( _("[Unnamed or unknown]") );
dest.Write(_("Path: "));
if (!StreamName.IsEmpty())
dest.Write(L"%s", WX_STR(StreamName));
else
dest.Write(_("[Unnamed or unknown]"));
if (!m_message_user.IsEmpty())
dest.Write(L"\n%s", WX_STR(m_message_user));
if (!m_message_user.IsEmpty())
dest.Write(L"\n%s", WX_STR(m_message_user));
}
// --------------------------------------------------------------------------------------
@ -334,19 +331,19 @@ void Exception::BadStream::_formatUserMsg( FastFormatUnicode& dest ) const
// --------------------------------------------------------------------------------------
wxString Exception::CannotCreateStream::FormatDiagnosticMessage() const
{
FastFormatUnicode retval;
retval.Write("File could not be created.");
_formatDiagMsg(retval);
return retval;
FastFormatUnicode retval;
retval.Write("File could not be created.");
_formatDiagMsg(retval);
return retval;
}
wxString Exception::CannotCreateStream::FormatDisplayMessage() const
{
FastFormatUnicode retval;
retval.Write(_("A file could not be created."));
retval.Write("\n");
_formatUserMsg(retval);
return retval;
FastFormatUnicode retval;
retval.Write(_("A file could not be created."));
retval.Write("\n");
_formatUserMsg(retval);
return retval;
}
// --------------------------------------------------------------------------------------
@ -354,19 +351,19 @@ wxString Exception::CannotCreateStream::FormatDisplayMessage() const
// --------------------------------------------------------------------------------------
wxString Exception::FileNotFound::FormatDiagnosticMessage() const
{
FastFormatUnicode retval;
retval.Write("File not found.\n");
_formatDiagMsg(retval);
return retval;
FastFormatUnicode retval;
retval.Write("File not found.\n");
_formatDiagMsg(retval);
return retval;
}
wxString Exception::FileNotFound::FormatDisplayMessage() const
{
FastFormatUnicode retval;
retval.Write(_("File not found."));
retval.Write("\n");
_formatUserMsg(retval);
return retval;
FastFormatUnicode retval;
retval.Write(_("File not found."));
retval.Write("\n");
_formatUserMsg(retval);
return retval;
}
// --------------------------------------------------------------------------------------
@ -374,19 +371,19 @@ wxString Exception::FileNotFound::FormatDisplayMessage() const
// --------------------------------------------------------------------------------------
wxString Exception::AccessDenied::FormatDiagnosticMessage() const
{
FastFormatUnicode retval;
retval.Write("Permission denied to file.\n");
_formatDiagMsg(retval);
return retval;
FastFormatUnicode retval;
retval.Write("Permission denied to file.\n");
_formatDiagMsg(retval);
return retval;
}
wxString Exception::AccessDenied::FormatDisplayMessage() const
{
FastFormatUnicode retval;
retval.Write(_("Permission denied while trying to open file, likely due to insufficient user account rights."));
retval.Write("\n");
_formatUserMsg(retval);
return retval;
FastFormatUnicode retval;
retval.Write(_("Permission denied while trying to open file, likely due to insufficient user account rights."));
retval.Write("\n");
_formatUserMsg(retval);
return retval;
}
// --------------------------------------------------------------------------------------
@ -394,19 +391,19 @@ wxString Exception::AccessDenied::FormatDisplayMessage() const
// --------------------------------------------------------------------------------------
wxString Exception::EndOfStream::FormatDiagnosticMessage() const
{
FastFormatUnicode retval;
retval.Write("Unexpected end of file or stream.\n");
_formatDiagMsg(retval);
return retval;
FastFormatUnicode retval;
retval.Write("Unexpected end of file or stream.\n");
_formatDiagMsg(retval);
return retval;
}
wxString Exception::EndOfStream::FormatDisplayMessage() const
{
FastFormatUnicode retval;
retval.Write(_("Unexpected end of file or stream encountered. File is probably truncated or corrupted."));
retval.Write("\n");
_formatUserMsg(retval);
return retval;
FastFormatUnicode retval;
retval.Write(_("Unexpected end of file or stream encountered. File is probably truncated or corrupted."));
retval.Write("\n");
_formatUserMsg(retval);
return retval;
}
// --------------------------------------------------------------------------------------
@ -415,35 +412,34 @@ wxString Exception::EndOfStream::FormatDisplayMessage() const
// Translates an Errno code into an exception.
// Throws an exception based on the given error code (usually taken from ANSI C's errno)
BaseException* Exception::FromErrno( const wxString& streamname, int errcode )
BaseException *Exception::FromErrno(const wxString &streamname, int errcode)
{
pxAssumeDev( errcode != 0, "Invalid NULL error code? (errno)" );
pxAssumeDev(errcode != 0, "Invalid NULL error code? (errno)");
switch( errcode )
{
case EINVAL:
pxFailDev( L"Invalid argument" );
return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Invalid argument? (likely caused by an unforgivable programmer error!)" );
switch (errcode) {
case EINVAL:
pxFailDev(L"Invalid argument");
return &(new Exception::BadStream(streamname))->SetDiagMsg(L"Invalid argument? (likely caused by an unforgivable programmer error!)");
case EACCES: // Access denied!
return new Exception::AccessDenied( streamname );
case EACCES: // Access denied!
return new Exception::AccessDenied(streamname);
case EMFILE: // Too many open files!
return &(new Exception::CannotCreateStream( streamname ))->SetDiagMsg(L"Too many open files"); // File handle allocation failure
case EMFILE: // Too many open files!
return &(new Exception::CannotCreateStream(streamname))->SetDiagMsg(L"Too many open files"); // File handle allocation failure
case EEXIST:
return &(new Exception::CannotCreateStream( streamname ))->SetDiagMsg(L"File already exists");
case EEXIST:
return &(new Exception::CannotCreateStream(streamname))->SetDiagMsg(L"File already exists");
case ENOENT: // File not found!
return new Exception::FileNotFound( streamname );
case ENOENT: // File not found!
return new Exception::FileNotFound(streamname);
case EPIPE:
return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Broken pipe");
case EPIPE:
return &(new Exception::BadStream(streamname))->SetDiagMsg(L"Broken pipe");
case EBADF:
return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Bad file number");
case EBADF:
return &(new Exception::BadStream(streamname))->SetDiagMsg(L"Bad file number");
default:
return &(new Exception::BadStream( streamname ))->SetDiagMsg(pxsFmt( L"General file/stream error [errno: %d]", errcode ));
}
default:
return &(new Exception::BadStream(streamname))->SetDiagMsg(pxsFmt(L"General file/stream error [errno: %d]", errcode));
}
}

View File

@ -24,9 +24,9 @@ template class SafeArray<char>;
template class SafeArray<wchar_t>;
template class SafeArray<u8>;
template class SafeAlignedArray<char,16>;
template class SafeAlignedArray<wchar_t,16>;
template class SafeAlignedArray<u8,16>;
template class SafeAlignedArray<char, 16>;
template class SafeAlignedArray<wchar_t, 16>;
template class SafeAlignedArray<u8, 16>;
// Sanity check: truncate strings if they exceed 512k in length. Anything like that
// is either a bug or really horrible code that needs to be stopped before it causes
@ -35,82 +35,86 @@ static const int MaxFormattedStringLength = 0x80000;
static
#ifndef __linux__
__ri
__ri
#endif
void format_that_ascii_mess( CharBufferType& buffer, uint writepos, const char* fmt, va_list argptr )
void
format_that_ascii_mess(CharBufferType &buffer, uint writepos, const char *fmt, va_list argptr)
{
va_list args;
while( true )
{
int size = buffer.GetLength();
va_list args;
while (true) {
int size = buffer.GetLength();
va_copy(args, argptr);
int len = vsnprintf(buffer.GetPtr(writepos), size-writepos, fmt, args);
va_end(args);
va_copy(args, argptr);
int len = vsnprintf(buffer.GetPtr(writepos), size - writepos, fmt, args);
va_end(args);
// some implementations of vsnprintf() don't NUL terminate
// the string if there is not enough space for it so
// always do it manually
buffer[size-1] = '\0';
// some implementations of vsnprintf() don't NUL terminate
// the string if there is not enough space for it so
// always do it manually
buffer[size - 1] = '\0';
if (size >= MaxFormattedStringLength) break;
if (size >= MaxFormattedStringLength)
break;
// vsnprintf() may return either -1 (traditional Unix behavior) or the
// total number of characters which would have been written if the
// buffer were large enough (newer standards such as Unix98)
// vsnprintf() may return either -1 (traditional Unix behavior) or the
// total number of characters which would have been written if the
// buffer were large enough (newer standards such as Unix98)
if (len < 0)
len = size + (size/4);
if (len < 0)
len = size + (size / 4);
len += writepos;
if (len < size) break;
buffer.Resize( len + 128 );
};
len += writepos;
if (len < size)
break;
buffer.Resize(len + 128);
};
// performing an assertion or log of a truncated string is unsafe, so let's not; even
// though it'd be kinda nice if we did.
// performing an assertion or log of a truncated string is unsafe, so let's not; even
// though it'd be kinda nice if we did.
}
// returns the length of the formatted string, in characters (wxChars).
static
#ifndef __linux__
__ri
__ri
#endif
uint format_that_unicode_mess( CharBufferType& buffer, uint writepos, const wxChar* fmt, va_list argptr)
uint
format_that_unicode_mess(CharBufferType &buffer, uint writepos, const wxChar *fmt, va_list argptr)
{
va_list args;
while( true )
{
int size = buffer.GetLength() / sizeof(wxChar);
va_list args;
while (true) {
int size = buffer.GetLength() / sizeof(wxChar);
va_copy(args, argptr);
int len = wxVsnprintf((wxChar*)buffer.GetPtr(writepos*sizeof(wxChar)), size-writepos, fmt, args);
va_end(args);
va_copy(args, argptr);
int len = wxVsnprintf((wxChar *)buffer.GetPtr(writepos * sizeof(wxChar)), size - writepos, fmt, args);
va_end(args);
// some implementations of vsnprintf() don't NUL terminate
// the string if there is not enough space for it so
// always do it manually
((wxChar*)buffer.GetPtr())[size-1] = L'\0';
// some implementations of vsnprintf() don't NUL terminate
// the string if there is not enough space for it so
// always do it manually
((wxChar *)buffer.GetPtr())[size - 1] = L'\0';
if( size >= MaxFormattedStringLength ) return size-1;
if (size >= MaxFormattedStringLength)
return size - 1;
// vsnprintf() may return either -1 (traditional Unix behavior) or the
// total number of characters which would have been written if the
// buffer were large enough (newer standards such as Unix98)
// vsnprintf() may return either -1 (traditional Unix behavior) or the
// total number of characters which would have been written if the
// buffer were large enough (newer standards such as Unix98)
if (len < 0)
len = size + (size/4);
if (len < 0)
len = size + (size / 4);
len += writepos;
if (len < size) return len;
buffer.Resize( (len + 128) * sizeof(wxChar) );
};
len += writepos;
if (len < size)
return len;
buffer.Resize((len + 128) * sizeof(wxChar));
};
// performing an assertion or log of a truncated string is unsafe, so let's not; even
// though it'd be kinda nice if we did.
// performing an assertion or log of a truncated string is unsafe, so let's not; even
// though it'd be kinda nice if we did.
pxAssume( false );
return 0; // unreachable.
pxAssume(false);
return 0; // unreachable.
}
// --------------------------------------------------------------------------------------
@ -123,9 +127,9 @@ uint format_that_unicode_mess( CharBufferType& buffer, uint writepos, const wxCh
// this class nicely in its current state. --air
FastFormatUnicode::FastFormatUnicode()
: m_dest(2048)
: m_dest(2048)
{
Clear();
Clear();
}
FastFormatUnicode::~FastFormatUnicode() throw()
@ -134,117 +138,117 @@ FastFormatUnicode::~FastFormatUnicode() throw()
void FastFormatUnicode::Clear()
{
m_Length = 0;
((wxChar*)m_dest.GetPtr())[0] = 0;
m_Length = 0;
((wxChar *)m_dest.GetPtr())[0] = 0;
}
FastFormatUnicode& FastFormatUnicode::WriteV( const char* fmt, va_list argptr )
FastFormatUnicode &FastFormatUnicode::WriteV(const char *fmt, va_list argptr)
{
wxString converted( fromUTF8(FastFormatAscii().WriteV( fmt, argptr )) );
wxString converted(fromUTF8(FastFormatAscii().WriteV(fmt, argptr)));
const uint inspos = m_Length;
const uint convLen = converted.Length();
m_dest.MakeRoomFor((inspos + convLen + 64) * sizeof(wxChar));
memcpy( &((wxChar*)m_dest.GetPtr())[inspos], converted.wc_str(), (convLen+1)*sizeof(wxChar) );
m_Length += convLen;
const uint inspos = m_Length;
const uint convLen = converted.Length();
m_dest.MakeRoomFor((inspos + convLen + 64) * sizeof(wxChar));
memcpy(&((wxChar *)m_dest.GetPtr())[inspos], converted.wc_str(), (convLen + 1) * sizeof(wxChar));
m_Length += convLen;
return *this;
return *this;
}
FastFormatUnicode& FastFormatUnicode::WriteV( const wxChar* fmt, va_list argptr )
FastFormatUnicode &FastFormatUnicode::WriteV(const wxChar *fmt, va_list argptr)
{
m_Length = format_that_unicode_mess( m_dest, m_Length, fmt, argptr );
return *this;
m_Length = format_that_unicode_mess(m_dest, m_Length, fmt, argptr);
return *this;
}
FastFormatUnicode& FastFormatUnicode::Write( const char* fmt, ... )
FastFormatUnicode &FastFormatUnicode::Write(const char *fmt, ...)
{
va_list list;
va_start(list, fmt);
WriteV(fmt,list);
va_end(list);
return *this;
va_list list;
va_start(list, fmt);
WriteV(fmt, list);
va_end(list);
return *this;
}
FastFormatUnicode& FastFormatUnicode::Write( const wxChar* fmt, ... )
FastFormatUnicode &FastFormatUnicode::Write(const wxChar *fmt, ...)
{
va_list list;
va_start(list, fmt);
WriteV(fmt,list);
va_end(list);
return *this;
va_list list;
va_start(list, fmt);
WriteV(fmt, list);
va_end(list);
return *this;
}
FastFormatUnicode& FastFormatUnicode::Write( const wxString fmt, ... )
FastFormatUnicode &FastFormatUnicode::Write(const wxString fmt, ...)
{
va_list list;
va_start(list, fmt);
WriteV(fmt.wx_str(),list);
va_end(list);
return *this;
va_list list;
va_start(list, fmt);
WriteV(fmt.wx_str(), list);
va_end(list);
return *this;
}
bool FastFormatUnicode::IsEmpty() const
{
return ((wxChar&)m_dest[0]) == 0;
return ((wxChar &)m_dest[0]) == 0;
}
FastFormatUnicode& FastFormatUnicode::ToUpper()
FastFormatUnicode &FastFormatUnicode::ToUpper()
{
wxChar* ch = (wxChar*)m_dest.GetPtr();
for ( uint i=0; i<m_Length; ++i, ++ch )
*ch = (wxChar)wxToupper(*ch);
wxChar *ch = (wxChar *)m_dest.GetPtr();
for (uint i = 0; i < m_Length; ++i, ++ch)
*ch = (wxChar)wxToupper(*ch);
return *this;
return *this;
}
FastFormatUnicode& FastFormatUnicode::ToLower()
FastFormatUnicode &FastFormatUnicode::ToLower()
{
wxChar* ch = (wxChar*)m_dest.GetPtr();
for ( uint i=0; i<m_Length; ++i, ++ch )
*ch = (wxChar)wxTolower(*ch);
wxChar *ch = (wxChar *)m_dest.GetPtr();
for (uint i = 0; i < m_Length; ++i, ++ch)
*ch = (wxChar)wxTolower(*ch);
return *this;
return *this;
}
FastFormatUnicode& FastFormatUnicode::operator+=(const char* psz )
FastFormatUnicode &FastFormatUnicode::operator+=(const char *psz)
{
Write( L"%s", WX_STR(fromUTF8(psz)) );
return *this;
Write(L"%s", WX_STR(fromUTF8(psz)));
return *this;
}
wxString& operator+=(wxString& str1, const FastFormatUnicode& str2)
wxString &operator+=(wxString &str1, const FastFormatUnicode &str2)
{
str1.Append(str2.c_str(), str2.Length());
return str1;
str1.Append(str2.c_str(), str2.Length());
return str1;
}
wxString operator+(const wxString& str1, const FastFormatUnicode& str2)
wxString operator+(const wxString &str1, const FastFormatUnicode &str2)
{
wxString s = str1;
s += str2;
return s;
wxString s = str1;
s += str2;
return s;
}
wxString operator+(const wxChar* str1, const FastFormatUnicode& str2)
wxString operator+(const wxChar *str1, const FastFormatUnicode &str2)
{
wxString s = str1;
s += str2;
return s;
wxString s = str1;
s += str2;
return s;
}
wxString operator+(const FastFormatUnicode& str1, const wxString& str2)
wxString operator+(const FastFormatUnicode &str1, const wxString &str2)
{
wxString s = str1;
s += str2;
return s;
wxString s = str1;
s += str2;
return s;
}
wxString operator+(const FastFormatUnicode& str1, const wxChar* str2)
wxString operator+(const FastFormatUnicode &str1, const wxChar *str2)
{
wxString s = str1;
s += str2;
return s;
wxString s = str1;
s += str2;
return s;
}
@ -252,9 +256,9 @@ wxString operator+(const FastFormatUnicode& str1, const wxChar* str2)
// FastFormatAscii (implementations)
// --------------------------------------------------------------------------------------
FastFormatAscii::FastFormatAscii()
: m_dest(2048)
: m_dest(2048)
{
Clear();
Clear();
}
FastFormatAscii::~FastFormatAscii() throw()
@ -263,31 +267,31 @@ FastFormatAscii::~FastFormatAscii() throw()
void FastFormatAscii::Clear()
{
m_dest.GetPtr()[0] = 0;
m_dest.GetPtr()[0] = 0;
}
const wxString FastFormatAscii::GetString() const
{
return fromAscii(m_dest.GetPtr());
return fromAscii(m_dest.GetPtr());
}
FastFormatAscii& FastFormatAscii::WriteV( const char* fmt, va_list argptr )
FastFormatAscii &FastFormatAscii::WriteV(const char *fmt, va_list argptr)
{
format_that_ascii_mess( m_dest, strlen(m_dest.GetPtr()), fmt, argptr );
return *this;
format_that_ascii_mess(m_dest, strlen(m_dest.GetPtr()), fmt, argptr);
return *this;
}
FastFormatAscii& FastFormatAscii::Write( const char* fmt, ... )
FastFormatAscii &FastFormatAscii::Write(const char *fmt, ...)
{
va_list list;
va_start(list, fmt);
WriteV(fmt,list);
va_end(list);
return *this;
va_list list;
va_start(list, fmt);
WriteV(fmt, list);
va_end(list);
return *this;
}
bool FastFormatAscii::IsEmpty() const
{
return m_dest[0] == 0;
return m_dest[0] == 0;
}

View File

@ -16,9 +16,10 @@
#include "PrecompiledHeader.h"
#include "HashMap.h"
namespace HashTools {
namespace HashTools
{
#define get16bits(d) (*((const u16 *) (d)))
#define get16bits(d) (*((const u16 *)(d)))
/// <summary>
/// Calculates a hash value for an arbitrary set of binary data.
@ -52,51 +53,53 @@ namespace HashTools {
/// uint32 hashval = Hash( (const char*)&data, sizeof( data ) );
/// </code>
/// </example>
u32 Hash(const s8 * data, int len)
u32 Hash(const s8 *data, int len)
{
u32 hash = len;
int rem;
u32 hash = len;
int rem;
if (len <= 0 || data == NULL) return 0;
if (len <= 0 || data == NULL)
return 0;
rem = len & 3;
len >>= 2;
rem = len & 3;
len >>= 2;
/* Main loop */
for (;len > 0; --len)
{
hash += get16bits (data);
u32 tmp = (get16bits (data+2) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2*sizeof (u16);
hash += hash >> 11;
}
/* Main loop */
for (; len > 0; --len) {
hash += get16bits(data);
u32 tmp = (get16bits(data + 2) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2 * sizeof(u16);
hash += hash >> 11;
}
/* Handle end cases */
switch (rem)
{
case 3: hash += get16bits (data);
hash ^= hash << 16;
hash ^= data[sizeof (u16)] << 18;
hash += hash >> 11;
break;
case 2: hash += get16bits (data);
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1: hash += *data;
hash ^= hash << 10;
hash += hash >> 1;
}
/* Handle end cases */
switch (rem) {
case 3:
hash += get16bits(data);
hash ^= hash << 16;
hash ^= data[sizeof(u16)] << 18;
hash += hash >> 11;
break;
case 2:
hash += get16bits(data);
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1:
hash += *data;
hash ^= hash << 10;
hash += hash >> 1;
}
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
return hash;
}
}

View File

@ -18,7 +18,7 @@
#include <wx/gdicmn.h>
const wxRect wxDefaultRect( wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord );
const wxRect wxDefaultRect(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord);
// Implement FixedPointTypes (for lack of a better location, for now)
@ -27,369 +27,396 @@ template struct FixedInt<100>;
template struct FixedInt<256>;
wxDirName g_fullBaseDirName = wxDirName(L"");
void SetFullBaseDir( wxDirName appRoot )
void SetFullBaseDir(wxDirName appRoot)
{
g_fullBaseDirName = appRoot;
g_fullBaseDirName = appRoot;
}
static int _calcEnumLength( const wxChar* const* enumArray )
static int _calcEnumLength(const wxChar *const *enumArray)
{
int cnt = 0;
while( *enumArray != NULL )
{
enumArray++;
cnt++;
}
int cnt = 0;
while (*enumArray != NULL) {
enumArray++;
cnt++;
}
return cnt;
return cnt;
}
ScopedIniGroup::ScopedIniGroup( IniInterface& mommy, const wxString& group )
: m_mom( mommy )
ScopedIniGroup::ScopedIniGroup(IniInterface &mommy, const wxString &group)
: m_mom(mommy)
{
pxAssertDev( wxStringTokenize( group, L"/" ).Count() <= 1, L"Cannot nest more than one group deep per instance of ScopedIniGroup." );
m_mom.SetPath( group );
pxAssertDev(wxStringTokenize(group, L"/").Count() <= 1, L"Cannot nest more than one group deep per instance of ScopedIniGroup.");
m_mom.SetPath(group);
}
ScopedIniGroup::~ScopedIniGroup()
{
m_mom.SetPath( L".." );
m_mom.SetPath(L"..");
}
// --------------------------------------------------------------------------------------
// IniInterface (implementations)
// --------------------------------------------------------------------------------------
IniInterface::IniInterface( wxConfigBase& config )
IniInterface::IniInterface(wxConfigBase &config)
{
m_Config = &config;
m_Config = &config;
}
IniInterface::IniInterface( wxConfigBase* config )
IniInterface::IniInterface(wxConfigBase *config)
{
m_Config = config;
m_Config = config;
}
IniInterface::IniInterface()
{
m_Config = wxConfigBase::Get( false );
m_Config = wxConfigBase::Get(false);
}
IniInterface::~IniInterface()
{
Flush();
Flush();
}
void IniInterface::SetPath( const wxString& path )
void IniInterface::SetPath(const wxString &path)
{
if( m_Config ) m_Config->SetPath( path );
if (m_Config)
m_Config->SetPath(path);
}
void IniInterface::Flush()
{
if( m_Config ) m_Config->Flush();
if (m_Config)
m_Config->Flush();
}
// --------------------------------------------------------------------------------------
// IniLoader (implementations)
// --------------------------------------------------------------------------------------
IniLoader::IniLoader( wxConfigBase& config ) : IniInterface( config ) { }
IniLoader::IniLoader( wxConfigBase* config ) : IniInterface( config ) { }
IniLoader::IniLoader(wxConfigBase &config)
: IniInterface(config)
{
}
IniLoader::IniLoader(wxConfigBase *config)
: IniInterface(config)
{
}
IniLoader::IniLoader() : IniInterface() {}
IniLoader::IniLoader()
: IniInterface()
{
}
IniLoader::~IniLoader() throw() {}
void IniLoader::Entry( const wxString& var, wxString& value, const wxString defvalue )
void IniLoader::Entry(const wxString &var, wxString &value, const wxString defvalue)
{
if( m_Config )
m_Config->Read( var, &value, defvalue );
else
value = defvalue;
if (m_Config)
m_Config->Read(var, &value, defvalue);
else
value = defvalue;
}
void IniLoader::Entry( const wxString& var, wxDirName& value, const wxDirName defvalue, bool isAllowRelative )
void IniLoader::Entry(const wxString &var, wxDirName &value, const wxDirName defvalue, bool isAllowRelative)
{
wxString dest;
if( m_Config ) m_Config->Read( var, &dest, wxEmptyString );
wxString dest;
if (m_Config)
m_Config->Read(var, &dest, wxEmptyString);
if( dest.IsEmpty() )
value = defvalue;
else
{
value = dest;
if( isAllowRelative )
value = g_fullBaseDirName + value;
if (dest.IsEmpty())
value = defvalue;
else {
value = dest;
if (isAllowRelative)
value = g_fullBaseDirName + value;
if( value.IsAbsolute() )
value.Normalize();
}
if (value.IsAbsolute())
value.Normalize();
}
}
void IniLoader::Entry( const wxString& var, wxFileName& value, const wxFileName defvalue, bool isAllowRelative )
void IniLoader::Entry(const wxString &var, wxFileName &value, const wxFileName defvalue, bool isAllowRelative)
{
wxString dest( defvalue.GetFullPath() );
if( m_Config ) m_Config->Read( var, &dest, defvalue.GetFullPath() );
value = dest;
if( isAllowRelative )
value = g_fullBaseDirName + value;
wxString dest(defvalue.GetFullPath());
if (m_Config)
m_Config->Read(var, &dest, defvalue.GetFullPath());
value = dest;
if (isAllowRelative)
value = g_fullBaseDirName + value;
if( value.IsAbsolute() )
value.Normalize();
if (value.IsAbsolute())
value.Normalize();
if (value.HasVolume())
value.SetVolume(value.GetVolume().Upper());
if (value.HasVolume())
value.SetVolume(value.GetVolume().Upper());
}
void IniLoader::Entry( const wxString& var, int& value, const int defvalue )
void IniLoader::Entry(const wxString &var, int &value, const int defvalue)
{
if( m_Config )
m_Config->Read( var, &value, defvalue );
else
value = defvalue;
if (m_Config)
m_Config->Read(var, &value, defvalue);
else
value = defvalue;
}
void IniLoader::Entry( const wxString& var, uint& value, const uint defvalue )
void IniLoader::Entry(const wxString &var, uint &value, const uint defvalue)
{
if( m_Config )
m_Config->Read( var, (int*)&value, (int)defvalue );
else
value = defvalue;
if (m_Config)
m_Config->Read(var, (int *)&value, (int)defvalue);
else
value = defvalue;
}
void IniLoader::Entry( const wxString& var, bool& value, const bool defvalue )
void IniLoader::Entry(const wxString &var, bool &value, const bool defvalue)
{
// TODO : Stricter value checking on enabled/disabled?
wxString dest(defvalue ? L"enabled" : L"disabled");
if( m_Config ) m_Config->Read( var, &dest, dest );
value = (dest == L"enabled") || (dest == L"1");
// TODO : Stricter value checking on enabled/disabled?
wxString dest(defvalue ? L"enabled" : L"disabled");
if (m_Config)
m_Config->Read(var, &dest, dest);
value = (dest == L"enabled") || (dest == L"1");
}
bool IniLoader::EntryBitBool( const wxString& var, bool value, const bool defvalue )
bool IniLoader::EntryBitBool(const wxString &var, bool value, const bool defvalue)
{
// Note: 'value' param is used by inisaver only.
bool result;
Entry( var, result, defvalue );
return result;
// Note: 'value' param is used by inisaver only.
bool result;
Entry(var, result, defvalue);
return result;
}
int IniLoader::EntryBitfield( const wxString& var, int value, const int defvalue )
int IniLoader::EntryBitfield(const wxString &var, int value, const int defvalue)
{
int result;
Entry( var, result, defvalue );
return result;
int result;
Entry(var, result, defvalue);
return result;
}
void IniLoader::Entry( const wxString& var, Fixed100& value, const Fixed100 defvalue )
void IniLoader::Entry(const wxString &var, Fixed100 &value, const Fixed100 defvalue)
{
// Note: the "easy" way would be to convert to double and load/save that, but floating point
// has way too much rounding error so we really need to do things out manually.. >_<
// Note: the "easy" way would be to convert to double and load/save that, but floating point
// has way too much rounding error so we really need to do things out manually.. >_<
wxString readval( value.ToString() );
if( m_Config ) m_Config->Read( var, &readval );
value = Fixed100::FromString( readval, value );
wxString readval(value.ToString());
if (m_Config)
m_Config->Read(var, &readval);
value = Fixed100::FromString(readval, value);
}
void IniLoader::Entry( const wxString& var, wxPoint& value, const wxPoint defvalue )
void IniLoader::Entry(const wxString &var, wxPoint &value, const wxPoint defvalue)
{
if( !m_Config )
{
value = defvalue; return;
}
TryParse( value, m_Config->Read( var, ToString( defvalue ) ), defvalue );
if (!m_Config) {
value = defvalue;
return;
}
TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue);
}
void IniLoader::Entry( const wxString& var, wxSize& value, const wxSize defvalue )
void IniLoader::Entry(const wxString &var, wxSize &value, const wxSize defvalue)
{
if( !m_Config )
{
value = defvalue; return;
}
TryParse( value, m_Config->Read( var, ToString( defvalue ) ), defvalue );
if (!m_Config) {
value = defvalue;
return;
}
TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue);
}
void IniLoader::Entry( const wxString& var, wxRect& value, const wxRect defvalue )
void IniLoader::Entry(const wxString &var, wxRect &value, const wxRect defvalue)
{
if( !m_Config )
{
value = defvalue; return;
}
TryParse( value, m_Config->Read( var, ToString( defvalue ) ), defvalue );
if (!m_Config) {
value = defvalue;
return;
}
TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue);
}
void IniLoader::_EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, int defvalue )
void IniLoader::_EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue)
{
// Confirm default value sanity...
// Confirm default value sanity...
const int cnt = _calcEnumLength( enumArray );
if( !IndexBoundsCheck( L"IniLoader EnumDefaultValue", defvalue, cnt ) )
{
Console.Error( "(LoadSettings) Default enumeration index is out of bounds. Truncating." );
defvalue = cnt-1;
}
const int cnt = _calcEnumLength(enumArray);
if (!IndexBoundsCheck(L"IniLoader EnumDefaultValue", defvalue, cnt)) {
Console.Error("(LoadSettings) Default enumeration index is out of bounds. Truncating.");
defvalue = cnt - 1;
}
// Sanity confirmed, proceed with craziness!
// Sanity confirmed, proceed with craziness!
if( !m_Config )
{
value = defvalue;
return;
}
if (!m_Config) {
value = defvalue;
return;
}
wxString retval;
m_Config->Read( var, &retval, enumArray[defvalue] );
wxString retval;
m_Config->Read(var, &retval, enumArray[defvalue]);
int i=0;
while( enumArray[i] != NULL && ( retval != enumArray[i] ) ) i++;
int i = 0;
while (enumArray[i] != NULL && (retval != enumArray[i]))
i++;
if( enumArray[i] == NULL )
{
Console.Warning( L"(LoadSettings) Warning: Unrecognized value '%s' on key '%s'\n\tUsing the default setting of '%s'.",
WX_STR(retval), WX_STR(var), enumArray[defvalue]
);
value = defvalue;
}
else
value = i;
if (enumArray[i] == NULL) {
Console.Warning(L"(LoadSettings) Warning: Unrecognized value '%s' on key '%s'\n\tUsing the default setting of '%s'.",
WX_STR(retval), WX_STR(var), enumArray[defvalue]);
value = defvalue;
} else
value = i;
}
// --------------------------------------------------------------------------------------
// IniSaver (implementations)
// --------------------------------------------------------------------------------------
IniSaver::IniSaver( wxConfigBase& config ) : IniInterface( config ) { }
IniSaver::IniSaver( wxConfigBase* config ) : IniInterface( config ) { }
IniSaver::IniSaver(wxConfigBase &config)
: IniInterface(config)
{
}
IniSaver::IniSaver(wxConfigBase *config)
: IniInterface(config)
{
}
IniSaver::IniSaver() : IniInterface() {}
IniSaver::IniSaver()
: IniInterface()
{
}
IniSaver::~IniSaver() {}
void IniSaver::Entry( const wxString& var, wxString& value, const wxString defvalue )
void IniSaver::Entry(const wxString &var, wxString &value, const wxString defvalue)
{
if( !m_Config ) return;
m_Config->Write( var, value );
if (!m_Config)
return;
m_Config->Write(var, value);
}
void IniSaver::Entry( const wxString& var, wxDirName& value, const wxDirName defvalue, bool isAllowRelative )
void IniSaver::Entry(const wxString &var, wxDirName &value, const wxDirName defvalue, bool isAllowRelative)
{
if( !m_Config ) return;
wxDirName res(value);
if (!m_Config)
return;
wxDirName res(value);
if ( res.IsAbsolute() )
res.Normalize();
if (isAllowRelative)
res = wxDirName::MakeAutoRelativeTo( res, g_fullBaseDirName.ToString() );
if (res.IsAbsolute())
res.Normalize();
if (isAllowRelative)
res = wxDirName::MakeAutoRelativeTo(res, g_fullBaseDirName.ToString());
/*if( value == defvalue )
/*if( value == defvalue )
m_Config->Write( var, wxString() );
else*/
m_Config->Write( var, res.ToString() );
m_Config->Write(var, res.ToString());
}
void IniSaver::Entry( const wxString& var, wxFileName& value, const wxFileName defvalue, bool isAllowRelative )
void IniSaver::Entry(const wxString &var, wxFileName &value, const wxFileName defvalue, bool isAllowRelative)
{
if( !m_Config ) return;
wxFileName res(value);
if (!m_Config)
return;
wxFileName res(value);
if ( res.IsAbsolute() )
res.Normalize();
if (isAllowRelative)
res = wxDirName::MakeAutoRelativeTo( res, g_fullBaseDirName.ToString() );
m_Config->Write( var, res.GetFullPath() );
if (res.IsAbsolute())
res.Normalize();
if (isAllowRelative)
res = wxDirName::MakeAutoRelativeTo(res, g_fullBaseDirName.ToString());
m_Config->Write(var, res.GetFullPath());
}
void IniSaver::Entry( const wxString& var, int& value, const int defvalue )
void IniSaver::Entry(const wxString &var, int &value, const int defvalue)
{
if( !m_Config ) return;
m_Config->Write( var, value );
if (!m_Config)
return;
m_Config->Write(var, value);
}
void IniSaver::Entry( const wxString& var, uint& value, const uint defvalue )
void IniSaver::Entry(const wxString &var, uint &value, const uint defvalue)
{
if( !m_Config ) return;
m_Config->Write( var, (int)value );
if (!m_Config)
return;
m_Config->Write(var, (int)value);
}
void IniSaver::Entry( const wxString& var, bool& value, const bool defvalue )
void IniSaver::Entry(const wxString &var, bool &value, const bool defvalue)
{
if( !m_Config ) return;
m_Config->Write( var, value ? L"enabled" : L"disabled" );
if (!m_Config)
return;
m_Config->Write(var, value ? L"enabled" : L"disabled");
}
bool IniSaver::EntryBitBool( const wxString& var, bool value, const bool defvalue )
bool IniSaver::EntryBitBool(const wxString &var, bool value, const bool defvalue)
{
if( m_Config ) m_Config->Write( var, value ? L"enabled" : L"disabled" );
return value;
if (m_Config)
m_Config->Write(var, value ? L"enabled" : L"disabled");
return value;
}
int IniSaver::EntryBitfield( const wxString& var, int value, const int defvalue )
int IniSaver::EntryBitfield(const wxString &var, int value, const int defvalue)
{
if( m_Config ) m_Config->Write( var, value );
return value;
if (m_Config)
m_Config->Write(var, value);
return value;
}
void IniSaver::Entry( const wxString& var, Fixed100& value, const Fixed100 defvalue )
void IniSaver::Entry(const wxString &var, Fixed100 &value, const Fixed100 defvalue)
{
if( !m_Config ) return;
if (!m_Config)
return;
// Note: the "easy" way would be to convert to double and load/save that, but floating point
// has way too much rounding error so we really need to do things out manually, using strings.
// Note: the "easy" way would be to convert to double and load/save that, but floating point
// has way too much rounding error so we really need to do things out manually, using strings.
m_Config->Write( var, value.ToString() );
m_Config->Write(var, value.ToString());
}
void IniSaver::Entry( const wxString& var, wxPoint& value, const wxPoint defvalue )
void IniSaver::Entry(const wxString &var, wxPoint &value, const wxPoint defvalue)
{
if( !m_Config ) return;
m_Config->Write( var, ToString( value ) );
if (!m_Config)
return;
m_Config->Write(var, ToString(value));
}
void IniSaver::Entry( const wxString& var, wxSize& value, const wxSize defvalue )
void IniSaver::Entry(const wxString &var, wxSize &value, const wxSize defvalue)
{
if( !m_Config ) return;
m_Config->Write( var, ToString( value ) );
if (!m_Config)
return;
m_Config->Write(var, ToString(value));
}
void IniSaver::Entry( const wxString& var, wxRect& value, const wxRect defvalue )
void IniSaver::Entry(const wxString &var, wxRect &value, const wxRect defvalue)
{
if( !m_Config ) return;
m_Config->Write( var, ToString( value ) );
if (!m_Config)
return;
m_Config->Write(var, ToString(value));
}
void IniSaver::_EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, int defvalue )
void IniSaver::_EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue)
{
const int cnt = _calcEnumLength( enumArray );
const int cnt = _calcEnumLength(enumArray);
// Confirm default value sanity...
// Confirm default value sanity...
if( !IndexBoundsCheck( L"IniSaver EnumDefaultValue", defvalue, cnt ) )
{
Console.Error( "(SaveSettings) Default enumeration index is out of bounds. Truncating." );
defvalue = cnt-1;
}
if (!IndexBoundsCheck(L"IniSaver EnumDefaultValue", defvalue, cnt)) {
Console.Error("(SaveSettings) Default enumeration index is out of bounds. Truncating.");
defvalue = cnt - 1;
}
if( !m_Config ) return;
if (!m_Config)
return;
if( value >= cnt )
{
Console.Warning( L"(SaveSettings) An illegal enumerated index was detected when saving '%s'", WX_STR(var) );
Console.Indent().Warning(
L"Illegal Value: %d\n"
L"Using Default: %d (%s)\n",
value, defvalue, enumArray[defvalue]
);
if (value >= cnt) {
Console.Warning(L"(SaveSettings) An illegal enumerated index was detected when saving '%s'", WX_STR(var));
Console.Indent().Warning(
L"Illegal Value: %d\n"
L"Using Default: %d (%s)\n",
value, defvalue, enumArray[defvalue]);
// Cause a debug assertion, since this is a fully recoverable error.
pxAssert( value < cnt );
// Cause a debug assertion, since this is a fully recoverable error.
pxAssert(value < cnt);
value = defvalue;
}
value = defvalue;
}
m_Config->Write( var, enumArray[value] );
m_Config->Write(var, enumArray[value]);
}

View File

@ -27,205 +27,206 @@
// Apple uses the MAP_ANON define instead of MAP_ANONYMOUS, but they mean
// the same thing.
#if defined(__APPLE__) && !defined(MAP_ANONYMOUS)
# define MAP_ANONYMOUS MAP_ANON
#define MAP_ANONYMOUS MAP_ANON
#endif
extern void SignalExit(int sig);
static const uptr m_pagemask = getpagesize()-1;
static const uptr m_pagemask = getpagesize() - 1;
// Linux implementation of SIGSEGV handler. Bind it using sigaction().
static void SysPageFaultSignalFilter( int signal, siginfo_t *siginfo, void * )
static void SysPageFaultSignalFilter(int signal, siginfo_t *siginfo, void *)
{
// [TODO] : Add a thread ID filter to the Linux Signal handler here.
// Rationale: On windows, the __try/__except model allows per-thread specific behavior
// for page fault handling. On linux, there is a single signal handler for the whole
// process, but the handler is executed by the thread that caused the exception.
// [TODO] : Add a thread ID filter to the Linux Signal handler here.
// Rationale: On windows, the __try/__except model allows per-thread specific behavior
// for page fault handling. On linux, there is a single signal handler for the whole
// process, but the handler is executed by the thread that caused the exception.
// Stdio Usage note: SIGSEGV handling is a synchronous in-thread signal. It is done
// from the context of the current thread and stackframe. So long as the thread is not
// the main/ui thread, use of the px assertion system should be safe. Use of stdio should
// be safe even on the main thread.
// (in other words, stdio limitations only really apply to process-level asynchronous
// signals)
// Stdio Usage note: SIGSEGV handling is a synchronous in-thread signal. It is done
// from the context of the current thread and stackframe. So long as the thread is not
// the main/ui thread, use of the px assertion system should be safe. Use of stdio should
// be safe even on the main thread.
// (in other words, stdio limitations only really apply to process-level asynchronous
// signals)
// Note: Use of stdio functions isn't safe here. Avoid console logs,
// assertions, file logs, or just about anything else useful.
// Note: Use of stdio functions isn't safe here. Avoid console logs,
// assertions, file logs, or just about anything else useful.
// Note: This signal can be accessed by the EE or MTVU thread
// Source_PageFault is a global variable with its own state information
// so for now we lock this exception code unless someone can fix this better...
Threading::ScopedLock lock(PageFault_Mutex);
// Note: This signal can be accessed by the EE or MTVU thread
// Source_PageFault is a global variable with its own state information
// so for now we lock this exception code unless someone can fix this better...
Threading::ScopedLock lock(PageFault_Mutex);
Source_PageFault->Dispatch( PageFaultInfo( (uptr)siginfo->si_addr & ~m_pagemask ) );
Source_PageFault->Dispatch(PageFaultInfo((uptr)siginfo->si_addr & ~m_pagemask));
// resumes execution right where we left off (re-executes instruction that
// caused the SIGSEGV).
if (Source_PageFault->WasHandled()) return;
// resumes execution right where we left off (re-executes instruction that
// caused the SIGSEGV).
if (Source_PageFault->WasHandled())
return;
if (!wxThread::IsMain())
{
pxFailRel(pxsFmt("Unhandled page fault @ 0x%08x", siginfo->si_addr));
}
if (!wxThread::IsMain()) {
pxFailRel(pxsFmt("Unhandled page fault @ 0x%08x", siginfo->si_addr));
}
// Bad mojo! Completely invalid address.
// Instigate a trap if we're in a debugger, and if not then do a SIGKILL.
// Bad mojo! Completely invalid address.
// Instigate a trap if we're in a debugger, and if not then do a SIGKILL.
pxTrap();
if (!IsDebugBuild) raise( SIGKILL );
pxTrap();
if (!IsDebugBuild)
raise(SIGKILL);
}
void _platform_InstallSignalHandler()
{
Console.WriteLn("Installing POSIX SIGSEGV handler...");
struct sigaction sa;
Console.WriteLn("Installing POSIX SIGSEGV handler...");
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = SysPageFaultSignalFilter;
sigaction(SIGSEGV, &sa, NULL);
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = SysPageFaultSignalFilter;
sigaction(SIGSEGV, &sa, NULL);
}
static __ri void PageSizeAssertionTest( size_t size )
static __ri void PageSizeAssertionTest(size_t size)
{
pxAssertMsg( (__pagesize == getpagesize()), pxsFmt(
"Internal system error: Operating system pagesize does not match compiled pagesize.\n\t"
L"\tOS Page Size: 0x%x (%d), Compiled Page Size: 0x%x (%u)",
getpagesize(), getpagesize(), __pagesize, __pagesize )
);
pxAssertMsg((__pagesize == getpagesize()), pxsFmt(
"Internal system error: Operating system pagesize does not match compiled pagesize.\n\t"
L"\tOS Page Size: 0x%x (%d), Compiled Page Size: 0x%x (%u)",
getpagesize(), getpagesize(), __pagesize, __pagesize));
pxAssertDev( (size & (__pagesize-1)) == 0, pxsFmt(
L"Memory block size must be a multiple of the target platform's page size.\n"
L"\tPage Size: 0x%x (%u), Block Size: 0x%x (%u)",
__pagesize, __pagesize, size, size )
);
pxAssertDev((size & (__pagesize - 1)) == 0, pxsFmt(
L"Memory block size must be a multiple of the target platform's page size.\n"
L"\tPage Size: 0x%x (%u), Block Size: 0x%x (%u)",
__pagesize, __pagesize, size, size));
}
// returns FALSE if the mprotect call fails with an ENOMEM.
// Raises assertions on other types of POSIX errors (since those typically reflect invalid object
// or memory states).
static bool _memprotect( void* baseaddr, size_t size, const PageProtectionMode& mode )
static bool _memprotect(void *baseaddr, size_t size, const PageProtectionMode &mode)
{
PageSizeAssertionTest(size);
PageSizeAssertionTest(size);
uint lnxmode = 0;
uint lnxmode = 0;
if (mode.CanWrite()) lnxmode |= PROT_WRITE;
if (mode.CanRead()) lnxmode |= PROT_READ;
if (mode.CanExecute()) lnxmode |= PROT_EXEC | PROT_READ;
if (mode.CanWrite())
lnxmode |= PROT_WRITE;
if (mode.CanRead())
lnxmode |= PROT_READ;
if (mode.CanExecute())
lnxmode |= PROT_EXEC | PROT_READ;
const int result = mprotect( baseaddr, size, lnxmode );
const int result = mprotect(baseaddr, size, lnxmode);
if (result == 0) return true;
if (result == 0)
return true;
switch(errno)
{
case EINVAL:
pxFailDev(pxsFmt(L"mprotect returned EINVAL @ 0x%08X -> 0x%08X (mode=%s)",
baseaddr, (uptr)baseaddr+size, WX_STR(mode.ToString()))
);
break;
switch (errno) {
case EINVAL:
pxFailDev(pxsFmt(L"mprotect returned EINVAL @ 0x%08X -> 0x%08X (mode=%s)",
baseaddr, (uptr)baseaddr + size, WX_STR(mode.ToString())));
break;
case EACCES:
pxFailDev(pxsFmt(L"mprotect returned EACCES @ 0x%08X -> 0x%08X (mode=%s)",
baseaddr, (uptr)baseaddr+size, WX_STR(mode.ToString()))
);
break;
case EACCES:
pxFailDev(pxsFmt(L"mprotect returned EACCES @ 0x%08X -> 0x%08X (mode=%s)",
baseaddr, (uptr)baseaddr + size, WX_STR(mode.ToString())));
break;
case ENOMEM:
// caller handles assertion or exception, or whatever.
break;
}
return false;
case ENOMEM:
// caller handles assertion or exception, or whatever.
break;
}
return false;
}
void* HostSys::MmapReservePtr(void* base, size_t size)
void *HostSys::MmapReservePtr(void *base, size_t size)
{
PageSizeAssertionTest(size);
PageSizeAssertionTest(size);
// On linux a reserve-without-commit is performed by using mmap on a read-only
// or anonymous source, with PROT_NONE (no-access) permission. Since the mapping
// is completely inaccessible, the OS will simply reserve it and will not put it
// against the commit table.
return mmap(base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
// On linux a reserve-without-commit is performed by using mmap on a read-only
// or anonymous source, with PROT_NONE (no-access) permission. Since the mapping
// is completely inaccessible, the OS will simply reserve it and will not put it
// against the commit table.
return mmap(base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
bool HostSys::MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode)
bool HostSys::MmapCommitPtr(void *base, size_t size, const PageProtectionMode &mode)
{
// In linux, reserved memory is automatically committed when its permissions are
// changed to something other than PROT_NONE. If the user is committing memory
// as PROT_NONE, then just ignore this call (memory will be committed automatically
// later when the user changes permissions to something useful via calls to MemProtect).
// In linux, reserved memory is automatically committed when its permissions are
// changed to something other than PROT_NONE. If the user is committing memory
// as PROT_NONE, then just ignore this call (memory will be committed automatically
// later when the user changes permissions to something useful via calls to MemProtect).
if (mode.IsNone()) return false;
if (mode.IsNone())
return false;
if (_memprotect( base, size, mode )) return true;
if (_memprotect(base, size, mode))
return true;
if (!pxDoOutOfMemory) return false;
pxDoOutOfMemory(size);
return _memprotect( base, size, mode );
if (!pxDoOutOfMemory)
return false;
pxDoOutOfMemory(size);
return _memprotect(base, size, mode);
}
void HostSys::MmapResetPtr(void* base, size_t size)
void HostSys::MmapResetPtr(void *base, size_t size)
{
// On linux the only way to reset the memory is to unmap and remap it as PROT_NONE.
// That forces linux to unload all committed pages and start from scratch.
// On linux the only way to reset the memory is to unmap and remap it as PROT_NONE.
// That forces linux to unload all committed pages and start from scratch.
// FIXME: Ideally this code would have some threading lock on it to prevent any other
// malloc/free code in the current process from interfering with the operation, but I
// can't think of any good way to do that. (generally it shouldn't be a problem in
// PCSX2 anyway, since MmapReset is only called when the ps2vm is suspended; so that
// pretty well stops all PCSX2 threads anyway).
// FIXME: Ideally this code would have some threading lock on it to prevent any other
// malloc/free code in the current process from interfering with the operation, but I
// can't think of any good way to do that. (generally it shouldn't be a problem in
// PCSX2 anyway, since MmapReset is only called when the ps2vm is suspended; so that
// pretty well stops all PCSX2 threads anyway).
Munmap(base, size);
void* result = MmapReservePtr(base, size);
Munmap(base, size);
void *result = MmapReservePtr(base, size);
pxAssertRel ((uptr)result == (uptr)base, pxsFmt(
"Virtual memory decommit failed: memory at 0x%08X -> 0x%08X could not be remapped. "
"This is likely caused by multi-thread memory contention.", base, (uptr)base+size
));
pxAssertRel((uptr)result == (uptr)base, pxsFmt(
"Virtual memory decommit failed: memory at 0x%08X -> 0x%08X could not be remapped. "
"This is likely caused by multi-thread memory contention.",
base, (uptr)base + size));
}
void* HostSys::MmapReserve(uptr base, size_t size)
void *HostSys::MmapReserve(uptr base, size_t size)
{
return MmapReservePtr((void*)base, size);
return MmapReservePtr((void *)base, size);
}
bool HostSys::MmapCommit(uptr base, size_t size, const PageProtectionMode& mode)
bool HostSys::MmapCommit(uptr base, size_t size, const PageProtectionMode &mode)
{
return MmapCommitPtr( (void*)base, size, mode );
return MmapCommitPtr((void *)base, size, mode);
}
void HostSys::MmapReset(uptr base, size_t size)
{
MmapResetPtr((void*)base, size);
MmapResetPtr((void *)base, size);
}
void* HostSys::Mmap(uptr base, size_t size)
void *HostSys::Mmap(uptr base, size_t size)
{
PageSizeAssertionTest(size);
PageSizeAssertionTest(size);
// MAP_ANONYMOUS - means we have no associated file handle (or device).
// MAP_ANONYMOUS - means we have no associated file handle (or device).
return mmap((void*)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
return mmap((void *)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
void HostSys::Munmap(uptr base, size_t size)
{
if (!base) return;
munmap((void*)base, size);
if (!base)
return;
munmap((void *)base, size);
}
void HostSys::MemProtect( void* baseaddr, size_t size, const PageProtectionMode& mode )
void HostSys::MemProtect(void *baseaddr, size_t size, const PageProtectionMode &mode)
{
if (!_memprotect(baseaddr, size, mode))
{
throw Exception::OutOfMemory( L"MemProtect" )
.SetDiagMsg(pxsFmt( L"mprotect failed @ 0x%08X -> 0x%08X (mode=%s)",
baseaddr, (uptr)baseaddr+size, WX_STR(mode.ToString())
)
);
}
if (!_memprotect(baseaddr, size, mode)) {
throw Exception::OutOfMemory(L"MemProtect")
.SetDiagMsg(pxsFmt(L"mprotect failed @ 0x%08X -> 0x%08X (mode=%s)",
baseaddr, (uptr)baseaddr + size, WX_STR(mode.ToString())));
}
}

View File

@ -24,13 +24,13 @@
// Returns 0 on failure (not supported by the operating system).
u64 GetPhysicalMemory()
{
u64 pages = 0;
u64 pages = 0;
#ifdef _SC_PHYS_PAGES
pages = sysconf(_SC_PHYS_PAGES);
pages = sysconf(_SC_PHYS_PAGES);
#endif
return pages * getpagesize();
return pages * getpagesize();
}
@ -40,22 +40,22 @@ void InitCPUTicks()
u64 GetTickFrequency()
{
return 1000000; // unix measures in microseconds
return 1000000; // unix measures in microseconds
}
u64 GetCPUTicks()
{
struct timeval t;
gettimeofday(&t, NULL);
return ((u64)t.tv_sec*GetTickFrequency())+t.tv_usec;
struct timeval t;
gettimeofday(&t, NULL);
return ((u64)t.tv_sec * GetTickFrequency()) + t.tv_usec;
}
wxString GetOSVersionString()
{
return wxGetOsDescription();
return wxGetOsDescription();
}
void ScreensaverAllow(bool allow)
{
// no-op
// no-op
}

View File

@ -29,7 +29,7 @@
#if !defined(__unix__)
# pragma message( "LnxThreads.cpp should only be compiled by projects or makefiles targeted at Linux/BSD distros.")
#pragma message("LnxThreads.cpp should only be compiled by projects or makefiles targeted at Linux/BSD distros.")
#else
@ -37,23 +37,23 @@
// the LOCK prefix. The prefix works on single core CPUs fine (but is slow), but not
// having the LOCK prefix is very bad indeed.
__forceinline void Threading::Sleep( int ms )
__forceinline void Threading::Sleep(int ms)
{
usleep( 1000*ms );
usleep(1000 * ms);
}
// For use in spin/wait loops, Acts as a hint to Intel CPUs and should, in theory
// improve performance and reduce cpu power consumption.
__forceinline void Threading::SpinWait()
{
// If this doesn't compile you can just comment it out (it only serves as a
// performance hint and isn't required).
__asm__ ( "pause" );
// If this doesn't compile you can just comment it out (it only serves as a
// performance hint and isn't required).
__asm__("pause");
}
__forceinline void Threading::EnableHiresScheduler()
{
// Don't know if linux has a customizable scheduler resolution like Windows (doubtful)
// Don't know if linux has a customizable scheduler resolution like Windows (doubtful)
}
__forceinline void Threading::DisableHiresScheduler()
@ -63,66 +63,69 @@ __forceinline void Threading::DisableHiresScheduler()
// Unit of time of GetThreadCpuTime/GetCpuTime
u64 Threading::GetThreadTicksPerSecond()
{
return 1000000;
return 1000000;
}
// Helper function to get either either the current cpu usage
// in called thread or in id thread
static u64 get_thread_time(uptr id = 0)
{
clockid_t cid;
if (id) {
int err = pthread_getcpuclockid((pthread_t)id, &cid);
if (err) return 0;
} else {
cid = CLOCK_THREAD_CPUTIME_ID;
}
clockid_t cid;
if (id) {
int err = pthread_getcpuclockid((pthread_t)id, &cid);
if (err)
return 0;
} else {
cid = CLOCK_THREAD_CPUTIME_ID;
}
struct timespec ts;
int err = clock_gettime(cid, &ts);
if (err) return 0;
struct timespec ts;
int err = clock_gettime(cid, &ts);
if (err)
return 0;
return (u64) ts.tv_sec * (u64) 1e6 + (u64) ts.tv_nsec / (u64) 1e3;
return (u64)ts.tv_sec * (u64)1e6 + (u64)ts.tv_nsec / (u64)1e3;
}
// Returns the current timestamp (not relative to a real world clock)
u64 Threading::GetThreadCpuTime()
{
return get_thread_time();
return get_thread_time();
}
u64 Threading::pxThread::GetCpuTime() const
{
// Get the cpu time for the thread belonging to this object. Use m_native_id and/or
// m_native_handle to implement it. Return value should be a measure of total time the
// thread has used on the CPU (scaled by the value returned by GetThreadTicksPerSecond(),
// which typically would be an OS-provided scalar or some sort).
// Get the cpu time for the thread belonging to this object. Use m_native_id and/or
// m_native_handle to implement it. Return value should be a measure of total time the
// thread has used on the CPU (scaled by the value returned by GetThreadTicksPerSecond(),
// which typically would be an OS-provided scalar or some sort).
if (!m_native_id) return 0;
if (!m_native_id)
return 0;
return get_thread_time(m_native_id);
return get_thread_time(m_native_id);
}
void Threading::pxThread::_platform_specific_OnStartInThread()
{
// Obtain linux-specific thread IDs or Handles here, which can be used to query
// kernel scheduler performance information.
m_native_id = (uptr) pthread_self();
// Obtain linux-specific thread IDs or Handles here, which can be used to query
// kernel scheduler performance information.
m_native_id = (uptr)pthread_self();
}
void Threading::pxThread::_platform_specific_OnCleanupInThread()
{
// Cleanup handles here, which were opened above.
// Cleanup handles here, which were opened above.
}
void Threading::pxThread::_DoSetThreadName( const char* name )
void Threading::pxThread::_DoSetThreadName(const char *name)
{
#if defined(__linux__)
// Extract of manpage: "The name can be up to 16 bytes long, and should be
// null-terminated if it contains fewer bytes."
prctl(PR_SET_NAME, name, 0, 0, 0);
// Extract of manpage: "The name can be up to 16 bytes long, and should be
// null-terminated if it contains fewer bytes."
prctl(PR_SET_NAME, name, 0, 0, 0);
#elif defined(__unix__)
pthread_set_name_np(pthread_self(), name);
pthread_set_name_np(pthread_self(), name);
#endif
}

View File

@ -23,8 +23,8 @@
namespace Threading
{
static std::atomic<int> _attr_refcount(0);
static pthread_mutexattr_t _attr_recursive;
static std::atomic<int> _attr_refcount(0);
static pthread_mutexattr_t _attr_recursive;
}
// --------------------------------------------------------------------------------------
@ -38,7 +38,7 @@ namespace Threading
// We have to emulate pthread_mutex_timedlock(). This could be a serious
// performance drain if its used a lot.
#include <sys/time.h> // gettimeofday()
#include <sys/time.h> // gettimeofday()
// sleep for 10ms at a time
#define TIMEDLOCK_EMU_SLEEP_NS 10000000ULL
@ -55,87 +55,91 @@ namespace Threading
// This is an implementation that emulates pthread_mutex_timedlock() via
// pthread_mutex_trylock().
static int xpthread_mutex_timedlock(
pthread_mutex_t *mutex,
const struct timespec *abs_timeout)
pthread_mutex_t *mutex,
const struct timespec *abs_timeout)
{
int err = 0;
int err = 0;
while ((err = pthread_mutex_trylock(mutex)) == EBUSY) {
// acquiring lock failed, sleep some
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = TIMEDLOCK_EMU_SLEEP_NS;
int status;
while ((status = nanosleep(&ts, &ts)) == -1);
while ((err = pthread_mutex_trylock(mutex)) == EBUSY) {
// acquiring lock failed, sleep some
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = TIMEDLOCK_EMU_SLEEP_NS;
int status;
while ((status = nanosleep(&ts, &ts)) == -1)
;
// check if the timeout has expired, gettimeofday() is implemented
// efficiently (in userspace) on OSX
struct timeval now;
int res = gettimeofday(&now, NULL);
if (abs_timeout->tv_sec == 0 || now.tv_sec > abs_timeout->tv_sec ||
(u64) now.tv_usec * 1000ULL > (u64) abs_timeout->tv_nsec) {
return ETIMEDOUT;
}
}
// check if the timeout has expired, gettimeofday() is implemented
// efficiently (in userspace) on OSX
struct timeval now;
int res = gettimeofday(&now, NULL);
if (abs_timeout->tv_sec == 0 || now.tv_sec > abs_timeout->tv_sec ||
(u64)now.tv_usec * 1000ULL > (u64)abs_timeout->tv_nsec) {
return ETIMEDOUT;
}
}
return err;
return err;
}
#endif
Threading::Mutex::Mutex()
{
pthread_mutex_init( &m_mutex, NULL );
pthread_mutex_init(&m_mutex, NULL);
}
static wxTimeSpan def_detach_timeout( 0, 0, 6, 0 );
static wxTimeSpan def_detach_timeout(0, 0, 6, 0);
void Threading::Mutex::Detach()
{
if( EBUSY != pthread_mutex_destroy(&m_mutex) ) return;
if (EBUSY != pthread_mutex_destroy(&m_mutex))
return;
if( IsRecursive() )
{
// Sanity check: Recursive locks could be held by our own thread, which would
// be considered an assertion failure, but can also be handled gracefully.
// (note: if the mutex is locked recursively more than twice then this assert won't
// detect it)
if (IsRecursive()) {
// Sanity check: Recursive locks could be held by our own thread, which would
// be considered an assertion failure, but can also be handled gracefully.
// (note: if the mutex is locked recursively more than twice then this assert won't
// detect it)
Release(); Release(); // in case of double recursion.
int result = pthread_mutex_destroy( &m_mutex );
if( pxAssertDev( result != EBUSY, "Detachment of a recursively-locked mutex (self-locked!)." ) ) return;
}
Release();
Release(); // in case of double recursion.
int result = pthread_mutex_destroy(&m_mutex);
if (pxAssertDev(result != EBUSY, "Detachment of a recursively-locked mutex (self-locked!)."))
return;
}
if( Wait(def_detach_timeout) )
pthread_mutex_destroy( &m_mutex );
else
Console.Error( "(Thread Log) Mutex cleanup failed due to possible deadlock.");
if (Wait(def_detach_timeout))
pthread_mutex_destroy(&m_mutex);
else
Console.Error("(Thread Log) Mutex cleanup failed due to possible deadlock.");
}
Threading::Mutex::~Mutex() throw()
{
try {
Mutex::Detach();
} DESTRUCTOR_CATCHALL;
try {
Mutex::Detach();
}
DESTRUCTOR_CATCHALL;
}
Threading::MutexRecursive::MutexRecursive() : Mutex( false )
Threading::MutexRecursive::MutexRecursive()
: Mutex(false)
{
if( ++_attr_refcount == 1 )
{
if( 0 != pthread_mutexattr_init( &_attr_recursive ) )
throw Exception::OutOfMemory(L"Recursive mutexing attributes");
if (++_attr_refcount == 1) {
if (0 != pthread_mutexattr_init(&_attr_recursive))
throw Exception::OutOfMemory(L"Recursive mutexing attributes");
pthread_mutexattr_settype( &_attr_recursive, PTHREAD_MUTEX_RECURSIVE );
}
pthread_mutexattr_settype(&_attr_recursive, PTHREAD_MUTEX_RECURSIVE);
}
if (pthread_mutex_init( &m_mutex, &_attr_recursive ))
Console.Error( "(Thread Log) Failed to initialize mutex.");
if (pthread_mutex_init(&m_mutex, &_attr_recursive))
Console.Error("(Thread Log) Failed to initialize mutex.");
}
Threading::MutexRecursive::~MutexRecursive() throw()
{
if( --_attr_refcount == 0 )
pthread_mutexattr_destroy( &_attr_recursive );
if (--_attr_refcount == 0)
pthread_mutexattr_destroy(&_attr_recursive);
}
// This is a bit of a hackish function, which is technically unsafe, but can be useful for allowing
@ -144,8 +148,8 @@ Threading::MutexRecursive::~MutexRecursive() throw()
// the deeper meanings of the universe for eternity.
void Threading::Mutex::Recreate()
{
Detach();
pthread_mutex_init( &m_mutex, NULL );
Detach();
pthread_mutex_init(&m_mutex, NULL);
}
// Returns:
@ -153,12 +157,11 @@ void Threading::Mutex::Recreate()
// unlocked.
bool Threading::Mutex::RecreateIfLocked()
{
if( !Wait(def_detach_timeout) )
{
Recreate();
return true;
}
return false;
if (!Wait(def_detach_timeout)) {
Recreate();
return true;
}
return false;
}
@ -168,25 +171,25 @@ bool Threading::Mutex::RecreateIfLocked()
// other than the main thread.
void Threading::Mutex::AcquireWithoutYield()
{
pxAssertMsg( !wxThread::IsMain(), "Unyielding mutex acquire issued from the main/gui thread. Please use Acquire() instead." );
pthread_mutex_lock( &m_mutex );
pxAssertMsg(!wxThread::IsMain(), "Unyielding mutex acquire issued from the main/gui thread. Please use Acquire() instead.");
pthread_mutex_lock(&m_mutex);
}
bool Threading::Mutex::AcquireWithoutYield( const wxTimeSpan& timeout )
bool Threading::Mutex::AcquireWithoutYield(const wxTimeSpan &timeout)
{
wxDateTime megafail( wxDateTime::UNow() + timeout );
const timespec fail = { megafail.GetTicks(), megafail.GetMillisecond() * 1000000 };
return xpthread_mutex_timedlock( &m_mutex, &fail ) == 0;
wxDateTime megafail(wxDateTime::UNow() + timeout);
const timespec fail = {megafail.GetTicks(), megafail.GetMillisecond() * 1000000};
return xpthread_mutex_timedlock(&m_mutex, &fail) == 0;
}
void Threading::Mutex::Release()
{
pthread_mutex_unlock( &m_mutex );
pthread_mutex_unlock(&m_mutex);
}
bool Threading::Mutex::TryAcquire()
{
return EBUSY != pthread_mutex_trylock( &m_mutex );
return EBUSY != pthread_mutex_trylock(&m_mutex);
}
// This is a wxApp-safe rendition of AcquireWithoutYield, which makes sure to execute pending app events
@ -195,54 +198,45 @@ bool Threading::Mutex::TryAcquire()
void Threading::Mutex::Acquire()
{
#if wxUSE_GUI
if( !wxThread::IsMain() || (wxTheApp == NULL) )
{
pthread_mutex_lock( &m_mutex );
}
else if( _WaitGui_RecursionGuard( L"Mutex::Acquire" ) )
{
ScopedBusyCursor hourglass( Cursor_ReallyBusy );
pthread_mutex_lock( &m_mutex );
}
else
{
//ScopedBusyCursor hourglass( Cursor_KindaBusy );
while( !AcquireWithoutYield(def_yieldgui_interval) )
YieldToMain();
}
if (!wxThread::IsMain() || (wxTheApp == NULL)) {
pthread_mutex_lock(&m_mutex);
} else if (_WaitGui_RecursionGuard(L"Mutex::Acquire")) {
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
pthread_mutex_lock(&m_mutex);
} else {
//ScopedBusyCursor hourglass( Cursor_KindaBusy );
while (!AcquireWithoutYield(def_yieldgui_interval))
YieldToMain();
}
#else
pthread_mutex_lock( &m_mutex );
pthread_mutex_lock(&m_mutex);
#endif
}
bool Threading::Mutex::Acquire( const wxTimeSpan& timeout )
bool Threading::Mutex::Acquire(const wxTimeSpan &timeout)
{
#if wxUSE_GUI
if( !wxThread::IsMain() || (wxTheApp == NULL) )
{
return AcquireWithoutYield(timeout);
}
else if( _WaitGui_RecursionGuard( L"Mutex::TimedAcquire" ) )
{
ScopedBusyCursor hourglass( Cursor_ReallyBusy );
return AcquireWithoutYield( timeout );
}
else
{
//ScopedBusyCursor hourglass( Cursor_KindaBusy );
wxTimeSpan countdown( (timeout) );
if (!wxThread::IsMain() || (wxTheApp == NULL)) {
return AcquireWithoutYield(timeout);
} else if (_WaitGui_RecursionGuard(L"Mutex::TimedAcquire")) {
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
return AcquireWithoutYield(timeout);
} else {
//ScopedBusyCursor hourglass( Cursor_KindaBusy );
wxTimeSpan countdown((timeout));
do {
if( AcquireWithoutYield( def_yieldgui_interval ) ) break;
YieldToMain();
countdown -= def_yieldgui_interval;
} while( countdown.GetMilliseconds() > 0 );
do {
if (AcquireWithoutYield(def_yieldgui_interval))
break;
YieldToMain();
countdown -= def_yieldgui_interval;
} while (countdown.GetMilliseconds() > 0);
return countdown.GetMilliseconds() > 0;
}
return countdown.GetMilliseconds() > 0;
}
#else
return AcquireWithoutYield();
return AcquireWithoutYield();
#endif
}
@ -255,14 +249,14 @@ bool Threading::Mutex::Acquire( const wxTimeSpan& timeout )
//
void Threading::Mutex::Wait()
{
Acquire();
Release();
Acquire();
Release();
}
void Threading::Mutex::WaitWithoutYield()
{
AcquireWithoutYield();
Release();
AcquireWithoutYield();
Release();
}
// Performs a wait on a locked mutex, or returns instantly if the mutex is unlocked.
@ -272,24 +266,22 @@ void Threading::Mutex::WaitWithoutYield()
// true if the mutex was freed and is in an unlocked state; or false if the wait timed out
// and the mutex is still locked by another thread.
//
bool Threading::Mutex::Wait( const wxTimeSpan& timeout )
bool Threading::Mutex::Wait(const wxTimeSpan &timeout)
{
if( Acquire(timeout) )
{
Release();
return true;
}
return false;
if (Acquire(timeout)) {
Release();
return true;
}
return false;
}
bool Threading::Mutex::WaitWithoutYield( const wxTimeSpan& timeout )
bool Threading::Mutex::WaitWithoutYield(const wxTimeSpan &timeout)
{
if( AcquireWithoutYield(timeout) )
{
Release();
return true;
}
return false;
if (AcquireWithoutYield(timeout)) {
Release();
return true;
}
return false;
}
// --------------------------------------------------------------------------------------
@ -298,67 +290,72 @@ bool Threading::Mutex::WaitWithoutYield( const wxTimeSpan& timeout )
Threading::ScopedLock::~ScopedLock() throw()
{
if( m_IsLocked && m_lock )
m_lock->Release();
if (m_IsLocked && m_lock)
m_lock->Release();
}
Threading::ScopedLock::ScopedLock( const Mutex* locker )
Threading::ScopedLock::ScopedLock(const Mutex *locker)
{
m_IsLocked = false;
AssignAndLock( locker );
m_IsLocked = false;
AssignAndLock(locker);
}
Threading::ScopedLock::ScopedLock( const Mutex& locker )
Threading::ScopedLock::ScopedLock(const Mutex &locker)
{
m_IsLocked = false;
AssignAndLock( locker );
m_IsLocked = false;
AssignAndLock(locker);
}
void Threading::ScopedLock::AssignAndLock( const Mutex& locker )
void Threading::ScopedLock::AssignAndLock(const Mutex &locker)
{
AssignAndLock( &locker );
AssignAndLock(&locker);
}
void Threading::ScopedLock::AssignAndLock( const Mutex* locker )
void Threading::ScopedLock::AssignAndLock(const Mutex *locker)
{
pxAssert(!m_IsLocked); // if we're already locked, changing the lock is bad mojo.
pxAssert(!m_IsLocked); // if we're already locked, changing the lock is bad mojo.
m_lock = const_cast<Mutex*>(locker);
if( !m_lock ) return;
m_lock = const_cast<Mutex *>(locker);
if (!m_lock)
return;
m_IsLocked = true;
m_lock->Acquire();
m_IsLocked = true;
m_lock->Acquire();
}
void Threading::ScopedLock::Assign( const Mutex& locker )
void Threading::ScopedLock::Assign(const Mutex &locker)
{
m_lock = const_cast<Mutex*>(&locker);
m_lock = const_cast<Mutex *>(&locker);
}
void Threading::ScopedLock::Assign( const Mutex* locker )
void Threading::ScopedLock::Assign(const Mutex *locker)
{
m_lock = const_cast<Mutex*>(locker);
m_lock = const_cast<Mutex *>(locker);
}
// Provides manual unlocking of a scoped lock prior to object destruction.
void Threading::ScopedLock::Release()
{
if( !m_IsLocked ) return;
m_IsLocked = false;
if( m_lock ) m_lock->Release();
if (!m_IsLocked)
return;
m_IsLocked = false;
if (m_lock)
m_lock->Release();
}
// provides manual locking of a scoped lock, to re-lock after a manual unlocking.
void Threading::ScopedLock::Acquire()
{
if( m_IsLocked || !m_lock ) return;
m_lock->Acquire();
m_IsLocked = true;
if (m_IsLocked || !m_lock)
return;
m_lock->Acquire();
m_IsLocked = true;
}
Threading::ScopedLock::ScopedLock( const Mutex& locker, bool isTryLock )
Threading::ScopedLock::ScopedLock(const Mutex &locker, bool isTryLock)
{
m_lock = const_cast<Mutex*>(&locker);
if( !m_lock ) return;
m_IsLocked = isTryLock ? m_lock->TryAcquire() : false;
m_lock = const_cast<Mutex *>(&locker);
if (!m_lock)
return;
m_IsLocked = isTryLock ? m_lock->TryAcquire() : false;
}

View File

@ -23,72 +23,74 @@
// wxDirName (implementations)
// ---------------------------------------------------------------------------------
wxFileName wxDirName::Combine( const wxFileName& right ) const
wxFileName wxDirName::Combine(const wxFileName &right) const
{
pxAssertMsg( IsDir(), L"Warning: Malformed directory name detected during wxDirName concatenation." );
if( right.IsAbsolute() )
return right;
pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wxDirName concatenation.");
if (right.IsAbsolute())
return right;
// Append any directory parts from right, and then set the filename.
// Except we can't do that because our m_members are private (argh!) and there is no API
// for getting each component of the path. So instead let's use Normalize:
// Append any directory parts from right, and then set the filename.
// Except we can't do that because our m_members are private (argh!) and there is no API
// for getting each component of the path. So instead let's use Normalize:
wxFileName result( right );
result.Normalize( wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE, GetPath() );
return result;
wxFileName result(right);
result.Normalize(wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE, GetPath());
return result;
}
wxDirName wxDirName::Combine( const wxDirName& right ) const
wxDirName wxDirName::Combine(const wxDirName &right) const
{
pxAssertMsg( IsDir() && right.IsDir(), L"Warning: Malformed directory name detected during wDirName concatenation." );
pxAssertMsg(IsDir() && right.IsDir(), L"Warning: Malformed directory name detected during wDirName concatenation.");
wxDirName result( right );
result.Normalize( wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE, GetPath() );
return result;
wxDirName result(right);
result.Normalize(wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE, GetPath());
return result;
}
wxDirName& wxDirName::Normalize( int flags, const wxString& cwd )
wxDirName &wxDirName::Normalize(int flags, const wxString &cwd)
{
pxAssertMsg( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
if( !wxFileName::Normalize( flags, cwd ) )
throw Exception::ParseError().SetDiagMsg( L"wxDirName::Normalize operation failed." );
return *this;
pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization.");
if (!wxFileName::Normalize(flags, cwd))
throw Exception::ParseError().SetDiagMsg(L"wxDirName::Normalize operation failed.");
return *this;
}
wxDirName& wxDirName::MakeRelativeTo( const wxString& pathBase )
wxDirName &wxDirName::MakeRelativeTo(const wxString &pathBase)
{
pxAssertMsg( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
if( !wxFileName::MakeRelativeTo( pathBase ) )
throw Exception::ParseError().SetDiagMsg( L"wxDirName::MakeRelativeTo operation failed." );
return *this;
pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization.");
if (!wxFileName::MakeRelativeTo(pathBase))
throw Exception::ParseError().SetDiagMsg(L"wxDirName::MakeRelativeTo operation failed.");
return *this;
}
wxDirName& wxDirName::MakeAbsolute( const wxString& cwd )
wxDirName &wxDirName::MakeAbsolute(const wxString &cwd)
{
pxAssertMsg( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
if( !wxFileName::MakeAbsolute( cwd ) )
throw Exception::ParseError().SetDiagMsg( L"wxDirName::MakeAbsolute operation failed." );
return *this;
pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization.");
if (!wxFileName::MakeAbsolute(cwd))
throw Exception::ParseError().SetDiagMsg(L"wxDirName::MakeAbsolute operation failed.");
return *this;
}
void wxDirName::Rmdir()
{
if( !Exists() ) return;
wxFileName::Rmdir();
// TODO : Throw exception if operation failed? Do we care?
if (!Exists())
return;
wxFileName::Rmdir();
// TODO : Throw exception if operation failed? Do we care?
}
bool wxDirName::Mkdir()
{
// wxWidgets recurses directory creation for us.
// wxWidgets recurses directory creation for us.
// only exist in wx2.9 and above
// only exist in wx2.9 and above
#ifndef wxS_DIR_DEFAULT
#define wxS_DIR_DEFAULT 0777
#endif
if( Exists() ) return true;
return wxFileName::Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
if (Exists())
return true;
return wxFileName::Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
}
@ -97,110 +99,111 @@ bool wxDirName::Mkdir()
// ---------------------------------------------------------------------------------
bool Path::IsRelative( const wxString& path )
bool Path::IsRelative(const wxString &path)
{
return wxDirName( path ).IsRelative();
return wxDirName(path).IsRelative();
}
// Returns -1 if the file does not exist.
s64 Path::GetFileSize( const wxString& path )
s64 Path::GetFileSize(const wxString &path)
{
if( !wxFile::Exists( path.c_str() ) ) return -1;
return (s64)wxFileName::GetSize( path ).GetValue();
if (!wxFile::Exists(path.c_str()))
return -1;
return (s64)wxFileName::GetSize(path).GetValue();
}
wxString Path::Normalize( const wxString& src )
wxString Path::Normalize(const wxString &src)
{
wxFileName normalize( src );
normalize.Normalize();
return normalize.GetFullPath();
wxFileName normalize(src);
normalize.Normalize();
return normalize.GetFullPath();
}
wxString Path::Normalize( const wxDirName& src )
wxString Path::Normalize(const wxDirName &src)
{
return wxDirName(src).Normalize().ToString();
return wxDirName(src).Normalize().ToString();
}
wxString Path::MakeAbsolute( const wxString& src )
wxString Path::MakeAbsolute(const wxString &src)
{
wxFileName absolute( src );
absolute.MakeAbsolute();
return absolute.GetFullPath();
wxFileName absolute(src);
absolute.MakeAbsolute();
return absolute.GetFullPath();
}
// Concatenates two pathnames together, inserting delimiters (backslash on win32)
// as needed! Assumes the 'dest' is allocated to at least g_MaxPath length.
//
wxString Path::Combine( const wxString& srcPath, const wxString& srcFile )
wxString Path::Combine(const wxString &srcPath, const wxString &srcFile)
{
return (wxDirName( srcPath ) + srcFile).GetFullPath();
return (wxDirName(srcPath) + srcFile).GetFullPath();
}
wxString Path::Combine( const wxDirName& srcPath, const wxFileName& srcFile )
wxString Path::Combine(const wxDirName &srcPath, const wxFileName &srcFile)
{
return (srcPath + srcFile).GetFullPath();
return (srcPath + srcFile).GetFullPath();
}
wxString Path::Combine( const wxString& srcPath, const wxDirName& srcFile )
wxString Path::Combine(const wxString &srcPath, const wxDirName &srcFile)
{
return (wxDirName( srcPath ) + srcFile).ToString();
return (wxDirName(srcPath) + srcFile).ToString();
}
// Replaces the extension of the file with the one given.
// This function works for path names as well as file names.
wxString Path::ReplaceExtension( const wxString& src, const wxString& ext )
wxString Path::ReplaceExtension(const wxString &src, const wxString &ext)
{
wxFileName jojo( src );
jojo.SetExt( ext );
return jojo.GetFullPath();
wxFileName jojo(src);
jojo.SetExt(ext);
return jojo.GetFullPath();
}
wxString Path::ReplaceFilename( const wxString& src, const wxString& newfilename )
wxString Path::ReplaceFilename(const wxString &src, const wxString &newfilename)
{
wxFileName jojo( src );
jojo.SetFullName( newfilename );
return jojo.GetFullPath();
wxFileName jojo(src);
jojo.SetFullName(newfilename);
return jojo.GetFullPath();
}
wxString Path::GetFilename( const wxString& src )
wxString Path::GetFilename(const wxString &src)
{
return wxFileName(src).GetFullName();
return wxFileName(src).GetFullName();
}
wxString Path::GetFilenameWithoutExt( const wxString& src )
wxString Path::GetFilenameWithoutExt(const wxString &src)
{
return wxFileName(src).GetName();
return wxFileName(src).GetName();
}
wxString Path::GetDirectory( const wxString& src )
wxString Path::GetDirectory(const wxString &src)
{
return wxFileName(src).GetPath();
return wxFileName(src).GetPath();
}
// returns the base/root directory of the given path.
// Example /this/that/something.txt -> dest == "/"
wxString Path::GetRootDirectory( const wxString& src )
wxString Path::GetRootDirectory(const wxString &src)
{
size_t pos = src.find_first_of( wxFileName::GetPathSeparators() );
if( pos == wxString::npos )
return wxString();
else
return wxString( src.begin(), src.begin()+pos );
size_t pos = src.find_first_of(wxFileName::GetPathSeparators());
if (pos == wxString::npos)
return wxString();
else
return wxString(src.begin(), src.begin() + pos);
}
// ------------------------------------------------------------------------
// Launches the specified file according to its mime type
//
void pxLaunch( const wxString& filename )
void pxLaunch(const wxString &filename)
{
wxLaunchDefaultBrowser( filename );
wxLaunchDefaultBrowser(filename);
}
void pxLaunch(const char *filename)
{
pxLaunch( fromUTF8(filename) );
pxLaunch(fromUTF8(filename));
}
// ------------------------------------------------------------------------
@ -209,12 +212,12 @@ void pxLaunch(const char *filename)
// bypasses wxWidgets internal filename checking, which can end up launching things
// through browser more often than desired.
//
void pxExplore( const wxString& path )
void pxExplore(const wxString &path)
{
wxLaunchDefaultBrowser( !path.Contains( L"://") ? L"file://" + path : path );
wxLaunchDefaultBrowser(!path.Contains(L"://") ? L"file://" + path : path);
}
void pxExplore(const char *path)
{
pxExplore( fromUTF8(path) );
pxExplore(fromUTF8(path));
}

View File

@ -23,118 +23,125 @@
namespace Perf
{
// Warning object aren't thread safe
InfoVector any("");
InfoVector ee("EE");
InfoVector iop("IOP");
InfoVector vu("VU");
// Warning object aren't thread safe
InfoVector any("");
InfoVector ee("EE");
InfoVector iop("IOP");
InfoVector vu("VU");
// Perf is only supported on linux
#if defined(__linux__) && defined(ProfileWithPerf)
////////////////////////////////////////////////////////////////////////////////
// Implementation of the Info object
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Implementation of the Info object
////////////////////////////////////////////////////////////////////////////////
Info::Info(uptr x86, u32 size, const char* symbol) : m_x86(x86), m_size(size), m_dynamic(false)
{
strncpy(m_symbol, symbol, sizeof(m_symbol));
}
Info::Info(uptr x86, u32 size, const char *symbol)
: m_x86(x86)
, m_size(size)
, m_dynamic(false)
{
strncpy(m_symbol, symbol, sizeof(m_symbol));
}
Info::Info(uptr x86, u32 size, const char* symbol, u32 pc) : m_x86(x86), m_size(size), m_dynamic(true)
{
snprintf(m_symbol, sizeof(m_symbol), "%s_0x%08x", symbol, pc);
}
Info::Info(uptr x86, u32 size, const char *symbol, u32 pc)
: m_x86(x86)
, m_size(size)
, m_dynamic(true)
{
snprintf(m_symbol, sizeof(m_symbol), "%s_0x%08x", symbol, pc);
}
void Info::Print(FILE* fp)
{
fprintf(fp, "%x %x %s\n", m_x86, m_size, m_symbol);
}
void Info::Print(FILE *fp)
{
fprintf(fp, "%x %x %s\n", m_x86, m_size, m_symbol);
}
////////////////////////////////////////////////////////////////////////////////
// Implementation of the InfoVector object
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Implementation of the InfoVector object
////////////////////////////////////////////////////////////////////////////////
InfoVector::InfoVector(const char* prefix)
{
strncpy(m_prefix, prefix, sizeof(m_prefix));
}
InfoVector::InfoVector(const char *prefix)
{
strncpy(m_prefix, prefix, sizeof(m_prefix));
}
void InfoVector::print(FILE* fp)
{
for(auto&& it : m_v) it.Print(fp);
}
void InfoVector::print(FILE *fp)
{
for (auto &&it : m_v)
it.Print(fp);
}
void InfoVector::map(uptr x86, u32 size, const char* symbol)
{
// This function is typically used for dispatcher and recompiler.
// Dispatchers are on a page and must always be kept.
// Recompilers are much bigger (TODO check VIF) and are only
// useful when MERGE_BLOCK_RESULT is defined
void InfoVector::map(uptr x86, u32 size, const char *symbol)
{
// This function is typically used for dispatcher and recompiler.
// Dispatchers are on a page and must always be kept.
// Recompilers are much bigger (TODO check VIF) and are only
// useful when MERGE_BLOCK_RESULT is defined
#ifdef MERGE_BLOCK_RESULT
m_v.emplace_back(x86, size, symbol);
m_v.emplace_back(x86, size, symbol);
#else
if (size < 8 * _1kb) m_v.emplace_back(x86, size, symbol);
if (size < 8 * _1kb)
m_v.emplace_back(x86, size, symbol);
#endif
}
void InfoVector::map(uptr x86, u32 size, u32 pc)
{
#ifndef MERGE_BLOCK_RESULT
m_v.emplace_back(x86, size, m_prefix, pc);
#endif
}
void InfoVector::reset()
{
auto dynamic = std::remove_if(m_v.begin(), m_v.end(), [](Info i) { return i.m_dynamic; });
m_v.erase(dynamic, m_v.end());
}
////////////////////////////////////////////////////////////////////////////////
// Global function
////////////////////////////////////////////////////////////////////////////////
void dump()
{
char file[256];
snprintf(file, 250, "/tmp/perf-%d.map", getpid());
FILE *fp = fopen(file, "w");
any.print(fp);
ee.print(fp);
iop.print(fp);
vu.print(fp);
if (fp)
fclose(fp);
}
void dump_and_reset()
{
dump();
any.reset();
ee.reset();
iop.reset();
vu.reset();
}
#else
////////////////////////////////////////////////////////////////////////////////
// Dummy implementation
////////////////////////////////////////////////////////////////////////////////
InfoVector::InfoVector(const char *prefix) {}
void InfoVector::map(uptr x86, u32 size, const char *symbol) {}
void InfoVector::map(uptr x86, u32 size, u32 pc) {}
void InfoVector::reset() {}
void dump() {}
void dump_and_reset() {}
#endif
}
void InfoVector::map(uptr x86, u32 size, u32 pc)
{
#ifndef MERGE_BLOCK_RESULT
m_v.emplace_back(x86, size, m_prefix, pc);
#endif
}
void InfoVector::reset()
{
auto dynamic = std::remove_if(m_v.begin(), m_v.end(), [](Info i) { return i.m_dynamic; });
m_v.erase(dynamic, m_v.end());
}
////////////////////////////////////////////////////////////////////////////////
// Global function
////////////////////////////////////////////////////////////////////////////////
void dump()
{
char file[256];
snprintf(file, 250, "/tmp/perf-%d.map", getpid());
FILE* fp = fopen(file, "w");
any.print(fp);
ee.print(fp);
iop.print(fp);
vu.print(fp);
if (fp)
fclose(fp);
}
void dump_and_reset()
{
dump();
any.reset();
ee.reset();
iop.reset();
vu.reset();
}
#else
////////////////////////////////////////////////////////////////////////////////
// Dummy implementation
////////////////////////////////////////////////////////////////////////////////
InfoVector::InfoVector(const char* prefix) {}
void InfoVector::map(uptr x86, u32 size, const char* symbol) {}
void InfoVector::map(uptr x86, u32 size, u32 pc) {}
void InfoVector::reset() {}
void dump() {}
void dump_and_reset() {}
#endif
}

View File

@ -28,4 +28,3 @@
#include "General.h"
#endif

Some files were not shown because too many files have changed in this diff Show More