diff --git a/common/AlignedMalloc.cpp b/common/AlignedMalloc.cpp index 570e056128..e0bc39fc1e 100644 --- a/common/AlignedMalloc.cpp +++ b/common/AlignedMalloc.cpp @@ -21,33 +21,34 @@ #include "common/Assertions.h" #include "common/ScopedAlloc.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); } #endif diff --git a/common/AppTrait.h b/common/AppTrait.h index 3816a9258a..2d837449b8 100644 --- a/common/AppTrait.h +++ b/common/AppTrait.h @@ -27,13 +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 }; diff --git a/common/Assertions.h b/common/Assertions.h index 75089c286b..a7d841d07d 100644 --- a/common/Assertions.h +++ b/common/Assertions.h @@ -27,7 +27,7 @@ #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 @@ -39,29 +39,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 @@ -159,11 +159,14 @@ extern pxDoAssertFnType *pxDoAssert; #define pxAssumeDev(cond, msg) (__assume(cond)) #define pxFail(msg) \ - do { \ - } while (0) + do \ + { \ + } while (0) + #define pxFailDev(msg) \ - do { \ - } while (0) + do \ + { \ + } while (0) #endif @@ -177,18 +180,18 @@ extern pxDoAssertFnType *pxDoAssert; // 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))) + 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))) + 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))) + 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))) + pxsFmt(L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze))) -extern void pxOnAssert(const DiagnosticOrigin &origin, const wxString &msg); +extern void pxOnAssert(const DiagnosticOrigin& origin, const wxString& msg); // -------------------------------------------------------------------------------------- // jNO_DEFAULT -- disables the default case in a switch, which improves switch optimization @@ -201,9 +204,10 @@ extern void pxOnAssert(const DiagnosticOrigin &origin, const wxString &msg); // * 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 diff --git a/common/CheckedStaticBox.cpp b/common/CheckedStaticBox.cpp index 80f1beb859..178acdc9ba 100644 --- a/common/CheckedStaticBox.cpp +++ b/common/CheckedStaticBox.cpp @@ -15,62 +15,64 @@ #include "common/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()); - evt.Skip(); + SetValue(evt.IsChecked()); + evt.Skip(); } // Sets the main checkbox status, and enables/disables all child controls // bound to the StaticBox accordingly. 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(IsEnabled() && val); - } - ThisToggle.SetValue(val); + for (wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter) + { + wxWindow* current = *iter; + if (current != &ThisToggle) + current->Enable(IsEnabled() && 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) { - 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; } diff --git a/common/CheckedStaticBox.h b/common/CheckedStaticBox.h index 2079c0a357..dbb9c254be 100644 --- a/common/CheckedStaticBox.h +++ b/common/CheckedStaticBox.h @@ -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); }; diff --git a/common/Console.cpp b/common/Console.cpp index 1c96101f0c..f64f735d80 100644 --- a/common/Console.cpp +++ b/common/Console.cpp @@ -26,11 +26,11 @@ static DeclareTls(int) conlog_Indent(0); static DeclareTls(ConsoleColors) conlog_Color(DefaultConsoleColor); #ifdef __POSIX__ -static FILE *stdout_fp = stdout; +static FILE* stdout_fp = stdout; -void Console_SetStdout(FILE *fp) +void Console_SetStdout(FILE* fp) { - stdout_fp = fp; + stdout_fp = fp; } #endif @@ -41,33 +41,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 } @@ -76,23 +76,23 @@ void MSW_OutputDebugString(const wxString &text) // ConsoleNull // -------------------------------------------------------------------------------------- -static void __concall ConsoleNull_SetTitle(const wxString &title) {} +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) }; // -------------------------------------------------------------------------------------- @@ -100,133 +100,134 @@ const IConsoleWriter ConsoleWriter_Null = // -------------------------------------------------------------------------------------- #if defined(__unix__) -static __fi const char *GetLinuxConsoleColor(ConsoleColors color) +static __fi const char* GetLinuxConsoleColor(ConsoleColors color) { - switch (color) { - case Color_Black: - case Color_StrongBlack: - return "\033[30m\033[1m"; + switch (color) + { + case Color_Black: + 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_StrongOrange: - case Color_StrongMagenta: - return "\033[35m\033[1m"; + // No orange, so use magenta. + case Color_Orange: + case Color_Magenta: + return "\033[35m"; + case Color_StrongOrange: + 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_StrongGray: - case Color_StrongWhite: - return "\033[37m\033[1m"; + // Use 'white' instead of grey. + case Color_Gray: + case Color_White: + return "\033[37m"; + case Color_StrongGray: + case Color_StrongWhite: + return "\033[37m\033[1m"; - // On some other value being passed, clear any formatting. - case Color_Default: - default: - return "\033[0m"; - } + // On some other value being passed, clear any formatting. + case Color_Default: + 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) { #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) }; // ===================================================================================================== @@ -239,170 +240,170 @@ 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 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; } // -------------------------------------------------------------------------------------- @@ -410,45 +411,45 @@ bool IConsoleWriter::Warning(const wxChar *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 { - 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 { - 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 { - 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; } @@ -458,70 +459,73 @@ bool IConsoleWriter::Warning(const wxString fmt, ...) const ConsoleColorScope::ConsoleColorScope(ConsoleColors newcolor) { - m_IsScoped = false; - m_newcolor = newcolor; - EnterScope(); + m_IsScoped = false; + m_newcolor = newcolor; + EnterScope(); } ConsoleColorScope::~ConsoleColorScope() { - 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) { - m_IsScoped = false; - m_amount = tabs; - EnterScope(); + m_IsScoped = false; + m_amount = tabs; + EnterScope(); } ConsoleIndentScope::~ConsoleIndentScope() { - 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) { - 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() { - try { - Console.SetColor(m_old_color); - Console.SetIndent(-m_tabsize); - } - DESTRUCTOR_CATCHALL + try + { + Console.SetColor(m_old_color); + Console.SetIndent(-m_tabsize); + } + DESTRUCTOR_CATCHALL } @@ -552,31 +556,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; } diff --git a/common/Console.h b/common/Console.h index 0a6eb2ef0a..18d25d7632 100644 --- a/common/Console.h +++ b/common/Console.h @@ -15,40 +15,41 @@ #pragma once -#include "StringHelpers.h" +#include "common/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; @@ -70,60 +71,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; }; // -------------------------------------------------------------------------------------- @@ -133,37 +134,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; } }; // -------------------------------------------------------------------------------------- @@ -179,19 +180,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(); - 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(); + void EnterScope(); + void LeaveScope(); }; // -------------------------------------------------------------------------------------- @@ -199,18 +200,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(); - void EnterScope(); - void LeaveScope(); + ConsoleColorScope(ConsoleColors newcolor); + virtual ~ConsoleColorScope(); + void EnterScope(); + void LeaveScope(); }; // -------------------------------------------------------------------------------------- @@ -220,23 +221,23 @@ 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(); + ConsoleAttrScope(ConsoleColors newcolor, int indent = 0); + virtual ~ConsoleAttrScope(); }; extern IConsoleWriter Console; #if defined(__unix__) || defined(__APPLE__) -extern void Console_SetStdout(FILE *fp); +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; @@ -250,7 +251,7 @@ extern bool DevConWriterEnabled; #ifdef PCSX2_DEVBUILD #define DevCon DevConWriter #else -#define DevCon DevConWriterEnabled &&DevConWriter +#define DevCon DevConWriterEnabled&& DevConWriter #endif #ifdef PCSX2_DEBUG diff --git a/common/Darwin/DarwinMisc.cpp b/common/Darwin/DarwinMisc.cpp index 3c512b828d..59bab47620 100644 --- a/common/Darwin/DarwinMisc.cpp +++ b/common/Darwin/DarwinMisc.cpp @@ -25,7 +25,7 @@ #include "common/Pcsx2Types.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 @@ -39,23 +39,25 @@ // 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() @@ -72,26 +74,28 @@ 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 @@ -100,53 +104,55 @@ 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 } #endif diff --git a/common/Darwin/DarwinSemaphore.cpp b/common/Darwin/DarwinSemaphore.cpp index 1ba1f3db1a..2a8135e241 100644 --- a/common/Darwin/DarwinSemaphore.cpp +++ b/common/Darwin/DarwinSemaphore.cpp @@ -20,10 +20,10 @@ #include // pthread_setcancelstate() #include // gettimeofday() #include -#include // semaphore_create() and semaphore_destroy() -#include // semaphore_*() +#include // semaphore_create() and semaphore_destroy() +#include // semaphore_*() #include // mach_error_string() -#include // mach_absolute_time() +#include // mach_absolute_time() #include "common/Threading.h" #include "common/ThreadingInternal.h" @@ -45,107 +45,113 @@ static void MACH_CHECK(kern_return_t mach_retval) { - switch (mach_retval) { - case KERN_SUCCESS: break; - case KERN_ABORTED: // Awoken due reason unrelated to semaphore (e.g. pthread_cancel) - pthread_testcancel(); // Unlike sem_wait, mach semaphore ops aren't cancellation points - // fallthrough - default: - fprintf(stderr, "mach error: %s", mach_error_string(mach_retval)); - assert(mach_retval == KERN_SUCCESS); - } + switch (mach_retval) + { + case KERN_SUCCESS: + break; + case KERN_ABORTED: // Awoken due reason unrelated to semaphore (e.g. pthread_cancel) + pthread_testcancel(); // Unlike sem_wait, mach semaphore ops aren't cancellation points + // fallthrough + default: + fprintf(stderr, "mach error: %s", mach_error_string(mach_retval)); + assert(mach_retval == KERN_SUCCESS); + } } 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() { - 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,18 +161,24 @@ 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 } @@ -179,29 +191,35 @@ 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 } @@ -220,22 +238,22 @@ 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); } #endif diff --git a/common/Darwin/DarwinThreads.cpp b/common/Darwin/DarwinThreads.cpp index 791f271094..a9a74879f5 100644 --- a/common/Darwin/DarwinThreads.cpp +++ b/common/Darwin/DarwinThreads.cpp @@ -29,27 +29,27 @@ __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() { - // Darwin has customizable schedulers, see xnu/osfmk/man. Not - // implemented yet though (and not sure if useful for pcsx2). + // Darwin has customizable schedulers, see xnu/osfmk/man. Not + // implemented yet though (and not sure if useful for pcsx2). } __forceinline void Threading::DisableHiresScheduler() { - // see EnableHiresScheduler() + // see EnableHiresScheduler() } // Just like on Windows, this is not really the number of ticks per second, @@ -58,27 +58,28 @@ __forceinline void Threading::DisableHiresScheduler() // doing this will of course yield precision loss. u64 Threading::GetThreadTicksPerSecond() { - return 1000000; // the *CpuTime() functions return values in microseconds + return 1000000; // the *CpuTime() functions return values in microseconds } // 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) { - mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT; - thread_basic_info_data_t info; + 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); - if (kr != KERN_SUCCESS) { - return 0; - } + kern_return_t kr = thread_info(thread, THREAD_BASIC_INFO, + (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; + // 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; } // Returns the current timestamp (not relative to a real world clock) in @@ -88,44 +89,45 @@ static u64 getthreadtime(thread_port_t thread) // not very good. u64 Threading::GetThreadCpuTime() { - // we could also use mach_thread_self() and mach_port_deallocate(), but - // that calls upon mach traps (kinda like system calls). Unless I missed - // something in the COMMPAGE (like Linux vDSO) which makes overrides it - // to be user-space instead. In contract, - // pthread_mach_thread_np(pthread_self()) is entirely in user-space. - u64 us = getthreadtime(pthread_mach_thread_np(pthread_self())); - return us * 10ULL; + // we could also use mach_thread_self() and mach_port_deallocate(), but + // that calls upon mach traps (kinda like system calls). Unless I missed + // something in the COMMPAGE (like Linux vDSO) which makes overrides it + // to be user-space instead. In contract, + // pthread_mach_thread_np(pthread_self()) is entirely in user-space. + u64 us = getthreadtime(pthread_mach_thread_np(pthread_self())); + return us * 10ULL; } 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). - if (!m_native_id) { - return 0; - } + // 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; + } - 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); + // cleanup of handles that were upened in + // _platform_specific_OnStartInThread + mach_port_deallocate(mach_task_self(), (thread_port_t)m_native_id); } // name can be up to 16 bytes -void Threading::SetNameOfCurrentThread(const char *name) +void Threading::SetNameOfCurrentThread(const char* name) { - pthread_setname_np(name); + pthread_setname_np(name); } #endif diff --git a/common/Dependencies.h b/common/Dependencies.h index 4e5aefe16d..fcc7ed917c 100644 --- a/common/Dependencies.h +++ b/common/Dependencies.h @@ -61,44 +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 { @@ -130,9 +134,9 @@ static const pxEnumEnd_t pxEnumEnd = {}; // #ifndef DeclareNoncopyableObject #define DeclareNoncopyableObject(classname) \ -private: \ - explicit classname(const classname &); \ - classname &operator=(const classname &) +private: \ + explicit classname(const classname&); \ + classname& operator=(const classname&) #endif @@ -144,19 +148,19 @@ private: \ 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() - { - *m_boolme = false; - } + ~ScopedBool() + { + *m_boolme = false; + } }; // -------------------------------------------------------------------------------------- @@ -218,7 +222,7 @@ public: #include #include // string.h under c++ -#include // stdio.h under c++ +#include // stdio.h under c++ #include #include #include @@ -262,12 +266,12 @@ static const s64 _4gb = _1gb * 4; #define pxE_dev(english) pxExpandMsg((english)) -extern const wxChar *__fastcall pxExpandMsg(const wxChar *message); -extern const wxChar *__fastcall pxGetTranslation(const wxChar *message); +extern const wxChar* __fastcall pxExpandMsg(const wxChar* message); +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 "common/Assertions.h" diff --git a/common/EmbeddedImage.h b/common/EmbeddedImage.h index 488efa6a9c..fc390b2162 100644 --- a/common/EmbeddedImage.h +++ b/common/EmbeddedImage.h @@ -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; }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -42,79 +42,80 @@ template 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; + } }; diff --git a/common/EventSource.h b/common/EventSource.h index d947d4c38d..67f61ec35d 100644 --- a/common/EventSource.h +++ b/common/EventSource.h @@ -26,54 +26,54 @@ template class EventSource { public: - typedef typename ListenerType::EvtParams EvtParams; - typedef typename std::list ListenerList; - typedef typename ListenerList::iterator ListenerIterator; + typedef typename ListenerType::EvtParams EvtParams; + typedef typename std::list 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() = default; + virtual ~EventSource() = default; - 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 ¶ms); + void Dispatch(const EvtParams& params); protected: - virtual ListenerIterator _AddFast_without_lock(ListenerType &listener); - virtual void _DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const EvtParams ¶ms); + virtual ListenerIterator _AddFast_without_lock(ListenerType& listener); + virtual void _DispatchRaw(ListenerIterator iter, const ListenerIterator& iend, const EvtParams& params); }; // -------------------------------------------------------------------------------------- @@ -86,9 +86,9 @@ template class IEventDispatcher { protected: - IEventDispatcher() {} + IEventDispatcher() {} public: - virtual ~IEventDispatcher() = default; - virtual void DispatchEvent(const EvtParams ¶ms) = 0; + virtual ~IEventDispatcher() = default; + virtual void DispatchEvent(const EvtParams& params) = 0; }; diff --git a/common/EventSource.inl b/common/EventSource.inl index 6a254e6e70..3269c47ec9 100644 --- a/common/EventSource.inl +++ b/common/EventSource.inl @@ -20,79 +20,92 @@ using Threading::ScopedLock; template -typename EventSource::ListenerIterator EventSource::Add(ListenerType &listener) +typename EventSource::ListenerIterator EventSource::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 -void EventSource::Remove(ListenerType &listener) +void EventSource::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 -void EventSource::Remove(const ListenerIterator &listenerHandle) +void EventSource::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 EventSource::ListenerIterator EventSource::_AddFast_without_lock(ListenerType &listener) +typename EventSource::ListenerIterator EventSource::_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 -__fi void EventSource::_DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const EvtParams &evtparams) +__fi void EventSource::_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 -void EventSource::Dispatch(const EvtParams &evtparams) +void EventSource::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); } diff --git a/common/Exceptions.cpp b/common/Exceptions.cpp index bc31ee4c6d..dd6f138067 100644 --- a/common/Exceptions.cpp +++ b/common/Exceptions.cpp @@ -42,28 +42,28 @@ Fnptr_OutOfMemory pxDoOutOfMemory = NULL; // That's ok. What we don't want is the *same* thread recurse-asserting. 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; } @@ -71,191 +71,196 @@ wxString DiagnosticOrigin::ToString(const wxChar *msg) const void pxTrap() { #if defined(__WXMSW__) && !defined(__WXMICROWIN__) - __debugbreak(); + __debugbreak(); #elif defined(__WXMAC__) && !defined(__DARWIN__) #if __powerc - Debugger(); + Debugger(); #else - SysBreak(); + SysBreak(); #endif #elif defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS - Debugger(); + Debugger(); #elif defined(__UNIX__) - raise(SIGTRAP); + raise(SIGTRAP); #else // 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 wxString &msg) +DEVASSERT_INLINE void pxOnAssert(const DiagnosticOrigin& origin, const wxString& 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.wc_str()); - } else { - trapit = pxDoAssert(origin, msg.wc_str()); - } + if (pxDoAssert == NULL) + { + // Note: Format uses MSVC's syntax for output window hotlinking. + trapit = pxAssertImpl_LogIt(origin, msg.wc_str()); + } + else + { + trapit = pxDoAssert(origin, msg.wc_str()); + } - if (trapit) { - pxTrap(); - } + if (trapit) + { + pxTrap(); + } } // -------------------------------------------------------------------------------------- // BaseException (implementations) // -------------------------------------------------------------------------------------- -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)); + if (!m_message_diag.IsEmpty()) + retmsg.Write(L":\n%s", WX_STR(m_message_diag)); - return retmsg; + 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)); + if (!m_message_diag.IsEmpty()) + retmsg.Write(L":\n%s", WX_STR(m_message_diag)); - return retmsg; + 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; } // -------------------------------------------------------------------------------------- @@ -263,40 +268,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)); } // -------------------------------------------------------------------------------------- @@ -304,19 +309,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; } // -------------------------------------------------------------------------------------- @@ -324,19 +329,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; } // -------------------------------------------------------------------------------------- @@ -344,19 +349,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; } // -------------------------------------------------------------------------------------- @@ -364,19 +369,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; } // -------------------------------------------------------------------------------------- @@ -385,34 +390,35 @@ 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)); + } } diff --git a/common/Exceptions.h b/common/Exceptions.h index 8367d33944..4ff7334feb 100644 --- a/common/Exceptions.h +++ b/common/Exceptions.h @@ -32,115 +32,121 @@ 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__) namespace Exception { -class BaseException; + class BaseException; -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() = default; + public: + virtual ~BaseException() = default; - 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 ScopedExcept; + typedef std::unique_ptr 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() = default; + public: + virtual ~Ps2Generic() = default; - 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: @@ -157,240 +163,254 @@ public: // (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() = default; \ - virtual void Rethrow() const { throw * this; } \ - virtual classname *Clone() const { return new classname(*this); } +private: \ + typedef parent _parent; \ +\ +public: \ + virtual ~classname() = default; \ +\ + 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) + DEFINE_EXCEPTION_COPYTORS(classname, parent) \ + classname() \ + { \ + SetDiagMsg(message); \ + } \ + DEFINE_EXCEPTION_MESSAGES(classname) -// --------------------------------------------------------------------------------------- -// RuntimeError - Generalized Exceptions with Recoverable Traits! -// --------------------------------------------------------------------------------------- + // --------------------------------------------------------------------------------------- + // RuntimeError - Generalized Exceptions with Recoverable Traits! + // --------------------------------------------------------------------------------------- -class RuntimeError : public BaseException -{ - DEFINE_EXCEPTION_COPYTORS(RuntimeError, BaseException) - DEFINE_EXCEPTION_MESSAGES(RuntimeError) + class RuntimeError : public BaseException + { + DEFINE_EXCEPTION_COPYTORS(RuntimeError, BaseException) + DEFINE_EXCEPTION_MESSAGES(RuntimeError) -public: - bool IsSilent; + public: + bool IsSilent; - RuntimeError() { IsSilent = false; } - RuntimeError(const std::runtime_error &ex, const wxString &prefix = wxEmptyString); - RuntimeError(const std::exception &ex, const wxString &prefix = wxEmptyString); -}; + RuntimeError() { IsSilent = false; } + RuntimeError(const std::runtime_error& ex, const wxString& prefix = wxEmptyString); + RuntimeError(const std::exception& ex, const wxString& prefix = wxEmptyString); + }; -// -------------------------------------------------------------------------------------- -// 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.")) + // -------------------------------------------------------------------------------------- + // 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: - explicit CancelEvent(const wxString &logmsg) - { - m_message_diag = logmsg; - // overridden message formatters only use the diagnostic version... - } + public: + explicit CancelEvent(const wxString& logmsg) + { + m_message_diag = logmsg; + // overridden message formatters only use the diagnostic version... + } - virtual wxString FormatDisplayMessage() const; - virtual wxString FormatDiagnosticMessage() const; -}; + virtual wxString FormatDisplayMessage() const; + virtual wxString FormatDiagnosticMessage() const; + }; -// --------------------------------------------------------------------------------------- -// 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) + // --------------------------------------------------------------------------------------- + // 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: - wxString AllocDescription; + public: + wxString AllocDescription; -public: - OutOfMemory(const wxString &allocdesc); + public: + OutOfMemory(const wxString& allocdesc); - virtual wxString FormatDisplayMessage() const; - virtual wxString FormatDiagnosticMessage() const; -}; + virtual wxString FormatDisplayMessage() const; + virtual wxString FormatDiagnosticMessage() const; + }; -class ParseError : public RuntimeError -{ - DEFINE_RUNTIME_EXCEPTION(ParseError, RuntimeError, pxL("Parse error")); -}; + class ParseError : public RuntimeError + { + DEFINE_RUNTIME_EXCEPTION(ParseError, RuntimeError, pxL("Parse error")); + }; -// --------------------------------------------------------------------------------------- -// Hardware/OS Exceptions: -// HardwareDeficiency / VirtualMemoryMapConflict -// --------------------------------------------------------------------------------------- + // --------------------------------------------------------------------------------------- + // Hardware/OS Exceptions: + // HardwareDeficiency / VirtualMemoryMapConflict + // --------------------------------------------------------------------------------------- -// 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) + // 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) - VirtualMemoryMapConflict(const wxString &allocdesc); + VirtualMemoryMapConflict(const wxString& allocdesc); - virtual wxString FormatDisplayMessage() const; - virtual wxString FormatDiagnosticMessage() const; -}; + virtual wxString FormatDisplayMessage() const; + virtual wxString FormatDiagnosticMessage() const; + }; -class HardwareDeficiency : public RuntimeError -{ -public: - DEFINE_RUNTIME_EXCEPTION(HardwareDeficiency, RuntimeError, pxL("Your machine's hardware is incapable of running PCSX2. Sorry dood.")); -}; + class HardwareDeficiency : public RuntimeError + { + public: + DEFINE_RUNTIME_EXCEPTION(HardwareDeficiency, RuntimeError, pxL("Your machine's hardware is incapable of running PCSX2. Sorry dood.")); + }; -// --------------------------------------------------------------------------------------- -// Streaming (file) Exceptions: -// Stream / BadStream / CannotCreateStream / FileNotFound / AccessDenied / EndOfStream -// --------------------------------------------------------------------------------------- + // --------------------------------------------------------------------------------------- + // Streaming (file) Exceptions: + // Stream / BadStream / CannotCreateStream / FileNotFound / AccessDenied / EndOfStream + // --------------------------------------------------------------------------------------- -#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; \ - } +#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; \ + } -#define DEFINE_STREAM_EXCEPTION(classname, parent) \ - DEFINE_RUNTIME_EXCEPTION(classname, parent, wxEmptyString) \ - classname(const wxString &filename) \ - { \ - StreamName = filename; \ - } \ - DEFINE_STREAM_EXCEPTION_ACCESSORS(classname) +#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) + // 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) -public: - wxString StreamName; // name of the stream (if applicable) + 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; -protected: - void _formatDiagMsg(FastFormatUnicode &dest) const; - void _formatUserMsg(FastFormatUnicode &dest) const; -}; + protected: + void _formatDiagMsg(FastFormatUnicode& dest) const; + void _formatUserMsg(FastFormatUnicode& dest) const; + }; -// A generic exception for odd-ball stream creation errors. -// -class CannotCreateStream : public BadStream -{ - DEFINE_STREAM_EXCEPTION(CannotCreateStream, BadStream) + // A generic exception for odd-ball stream creation errors. + // + class CannotCreateStream : public BadStream + { + DEFINE_STREAM_EXCEPTION(CannotCreateStream, BadStream) - 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) + // 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) - 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) + 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; + }; -// 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) + // 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; + }; #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 -} +} // namespace Exception using Exception::BaseException; using Exception::ScopedExcept; diff --git a/common/FastFormatString.cpp b/common/FastFormatString.cpp index adb1b79ad8..a6d73e5e50 100644 --- a/common/FastFormatString.cpp +++ b/common/FastFormatString.cpp @@ -33,88 +33,88 @@ template class SafeAlignedArray; // system deadlock. static const int MaxFormattedStringLength = 0x80000; -static #ifndef __linux__ - __ri +static __ri void format_that_ascii_mess(CharBufferType& buffer, uint writepos, const char* fmt, va_list argptr) +#else +static void format_that_ascii_mess(CharBufferType& buffer, uint writepos, const char* fmt, va_list argptr) #endif - 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 +static __ri uint format_that_unicode_mess(CharBufferType& buffer, uint writepos, const wxChar* fmt, va_list argptr) +#else +static uint format_that_unicode_mess(CharBufferType& buffer, uint writepos, const wxChar* fmt, va_list argptr) #endif - 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. } // -------------------------------------------------------------------------------------- @@ -127,124 +127,124 @@ static // this class nicely in its current state. --air FastFormatUnicode::FastFormatUnicode() - : m_dest(2048) + : m_dest(2048) { - Clear(); + Clear(); } 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,38 +252,38 @@ wxString operator+(const FastFormatUnicode &str1, const wxChar *str2) // FastFormatAscii (implementations) // -------------------------------------------------------------------------------------- FastFormatAscii::FastFormatAscii() - : m_dest(2048) + : m_dest(2048) { - Clear(); + Clear(); } 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; } diff --git a/common/General.h b/common/General.h index ad72cd06de..f8c102a976 100644 --- a/common/General.h +++ b/common/General.h @@ -26,17 +26,15 @@ // Macro used for removing some of the redtape involved in defining bitfield/union helpers. // #define BITFIELD32() \ - union \ - { \ - u32 bitset; \ - struct \ - { + union \ + { \ + u32 bitset; \ + struct \ + { #define BITFIELD_END \ - } \ - ; \ - } \ - ; + }; \ + }; // ---------------------------------------------------------------------------------------- @@ -52,20 +50,20 @@ class RecursionGuard { public: - int &Counter; + int& Counter; - RecursionGuard(int &counter) - : Counter(counter) - { - ++Counter; - } + RecursionGuard(int& counter) + : Counter(counter) + { + ++Counter; + } - virtual ~RecursionGuard() - { - --Counter; - } + virtual ~RecursionGuard() + { + --Counter; + } - bool IsReentrant() const { return Counter > 1; } + bool IsReentrant() const { return Counter > 1; } }; // -------------------------------------------------------------------------------------- @@ -74,30 +72,30 @@ public: class IActionInvocation { public: - virtual ~IActionInvocation() = default; - virtual void InvokeAction() = 0; + virtual ~IActionInvocation() = default; + virtual void InvokeAction() = 0; }; class ICloneable { public: - virtual ICloneable *Clone() const = 0; + virtual ICloneable* Clone() const = 0; }; class IDeletableObject { public: - virtual ~IDeletableObject() = default; + virtual ~IDeletableObject() = default; - 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; }; // -------------------------------------------------------------------------------------- @@ -126,26 +124,26 @@ protected: class BaseDeletableObject : public virtual IDeletableObject { protected: - std::atomic m_IsBeingDeleted; + std::atomic m_IsBeingDeleted; public: - BaseDeletableObject(); - virtual ~BaseDeletableObject(); + BaseDeletableObject(); + virtual ~BaseDeletableObject(); - 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(); }; // -------------------------------------------------------------------------------------- @@ -154,76 +152,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& Execute(bool allow = true) + { + m_exec = allow; + return *this; + } - PageProtectionMode &All(bool allow = true) - { - m_read = m_write = m_exec = allow; - return *this; - } + 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; } + 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; + 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(); } // -------------------------------------------------------------------------------------- @@ -233,35 +231,35 @@ 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 -void MemProtectStatic(u8 (&arr)[size], const PageProtectionMode &mode) -{ - MemProtect(arr, size, mode); -} -} + template + void MemProtectStatic(u8 (&arr)[size], const PageProtectionMode& mode) + { + MemProtect(arr, size, mode); + } +} // namespace HostSys // 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)) + ((void)(HostSys::Munmap((uptr)(ptr), size), (ptr) = NULL)) extern void InitCPUTicks(); extern u64 GetTickFrequency(); diff --git a/common/IniInterface.cpp b/common/IniInterface.cpp index 90b1354eb4..ebb0af9b84 100644 --- a/common/IniInterface.cpp +++ b/common/IniInterface.cpp @@ -23,393 +23,404 @@ const wxRect wxDefaultRect(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDef wxDirName g_fullBaseDirName = wxDirName(L""); 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() + : IniInterface() { } -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; - if(defvalue) - dest = wxString("enabled"); - else - dest = wxString("disabled"); + // TODO : Stricter value checking on enabled/disabled? + wxString dest; + if (defvalue) + dest = wxString("enabled"); + else + dest = wxString("disabled"); - if (m_Config) - m_Config->Read(var, &dest, dest); - value = (dest == L"enabled") || (dest == L"1"); + 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, double& value, const double defvalue) +void IniLoader::Entry(const wxString& var, double& value, const double defvalue) { - auto readval = wxString::FromDouble(value); + auto readval = wxString::FromDouble(value); - if (m_Config) - m_Config->Read(var, &readval); + if (m_Config) + m_Config->Read(var, &readval); - if (!readval.ToDouble(&value)) - value = 0.0; + if (!readval.ToDouble(&value)) + value = 0.0; } -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() + : IniInterface() { } -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 (res.IsAbsolute()) + res.Normalize(); - if (isAllowRelative) - res = wxDirName::MakeAutoRelativeTo(res, g_fullBaseDirName.ToString()); + 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 (res.IsAbsolute()) + res.Normalize(); - if (isAllowRelative) - res = wxDirName::MakeAutoRelativeTo(res, g_fullBaseDirName.ToString()); + if (isAllowRelative) + res = wxDirName::MakeAutoRelativeTo(res, g_fullBaseDirName.ToString()); - m_Config->Write(var, res.GetFullPath()); + 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, double &value, const double defvalue) +void IniSaver::Entry(const wxString& var, double& value, const double defvalue) { - if (!m_Config) - return; + if (!m_Config) + return; - m_Config->Write(var, wxString::FromDouble(value)); + m_Config->Write(var, wxString::FromDouble(value)); } -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]); } diff --git a/common/IniInterface.h b/common/IniInterface.h index a829bf4d63..c68ac98d70 100644 --- a/common/IniInterface.h +++ b/common/IniInterface.h @@ -31,58 +31,58 @@ 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, double& value, const double defvalue = 0.0) = 0; + virtual void Entry(const wxString& var, double& value, const double defvalue = 0.0) = 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 - void EnumEntry(const wxString &var, T &value, const wxChar *const *enumArray = NULL, const T defvalue = (T)0) - { - int tstore = (int)value; - auto defaultvalue = enum_cast(defvalue); - if (enumArray == NULL) - Entry(var, tstore, defaultvalue); - else - _EnumEntry(var, tstore, enumArray, defaultvalue); - value = (T)tstore; - } + template + void EnumEntry(const wxString& var, T& value, const wxChar* const* enumArray = NULL, const T defvalue = (T)0) + { + int tstore = (int)value; + auto defaultvalue = enum_cast(defvalue); + if (enumArray == NULL) + Entry(var, tstore, defaultvalue); + else + _EnumEntry(var, tstore, enumArray, defaultvalue); + 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; }; // -------------------------------------------------------------------------------------- @@ -91,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(); }; // -------------------------------------------------------------------------------------- @@ -109,31 +109,31 @@ public: class IniLoader : public IniInterface { public: - virtual ~IniLoader() = default; - explicit IniLoader(); - explicit IniLoader(wxConfigBase &config); - explicit IniLoader(wxConfigBase *config); + virtual ~IniLoader() = default; + 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, double& value, const double defvalue = 0.0) override; + void Entry(const wxString& var, double& value, const double defvalue = 0.0) override; - 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); }; // -------------------------------------------------------------------------------------- @@ -147,31 +147,31 @@ protected: class IniSaver : public IniInterface { public: - virtual ~IniSaver() = default; - explicit IniSaver(); - explicit IniSaver(wxConfigBase &config); - explicit IniSaver(wxConfigBase *config); + virtual ~IniSaver() = default; + 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, double &value, const double defvalue = 0.0) override; + void Entry(const wxString& var, double& value, const double defvalue = 0.0) override; - 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); }; // ------------------------------------------------------------------------ diff --git a/common/Linux/LnxHostSys.cpp b/common/Linux/LnxHostSys.cpp index 20d72a552a..757592d33e 100644 --- a/common/Linux/LnxHostSys.cpp +++ b/common/Linux/LnxHostSys.cpp @@ -33,195 +33,198 @@ extern void SignalExit(int sig); 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; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = SysPageFaultSignalFilter; #ifdef __APPLE__ - // MacOS uses SIGBUS for memory permission violations - sigaction(SIGBUS, &sa, NULL); + // MacOS uses SIGBUS for memory permission violations + sigaction(SIGBUS, &sa, NULL); #else - sigaction(SIGSEGV, &sa, NULL); + sigaction(SIGSEGV, &sa, NULL); #endif } 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) { - PageSizeAssertionTest(size); + PageSizeAssertionTest(size); - void *result = mmap(base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); + void* result = mmap(base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); - pxAssertRel((uptr)result == (uptr)base, pxsFmt( - "Virtual memory decommit failed: memory at 0x%08X -> 0x%08X could not be remapped.", - base, (uptr)base + size)); + pxAssertRel((uptr)result == (uptr)base, pxsFmt( + "Virtual memory decommit failed: memory at 0x%08X -> 0x%08X could not be remapped.", + 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()))); + } } #endif diff --git a/common/Linux/LnxThreads.cpp b/common/Linux/LnxThreads.cpp index c680f69d7f..f57eb31a86 100644 --- a/common/Linux/LnxThreads.cpp +++ b/common/Linux/LnxThreads.cpp @@ -39,21 +39,21 @@ __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,69 +63,72 @@ __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::SetNameOfCurrentThread(const char *name) +void Threading::SetNameOfCurrentThread(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 } diff --git a/common/MathUtils.h b/common/MathUtils.h index 7aae82d6f6..5a85d97d28 100644 --- a/common/MathUtils.h +++ b/common/MathUtils.h @@ -22,20 +22,20 @@ // 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; + // 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. #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 } diff --git a/common/MemcpyFast.h b/common/MemcpyFast.h index 592b5df0a1..a42afc4b4e 100644 --- a/common/MemcpyFast.h +++ b/common/MemcpyFast.h @@ -22,7 +22,7 @@ // 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 @@ -31,14 +31,14 @@ extern u8 memcmp_mmx(const void *src1, const void *src2, int cmpsize); // Structures, static arrays, etc. No need to include sizeof() crap, this does it automatically // for you! template -static __fi void memzero(T &object) +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 -static __fi void memset8(T &object) +static __fi void memset8(T& object) { - memset(&object, data, sizeof(T)); + memset(&object, data, sizeof(T)); } diff --git a/common/MemsetFast.inl b/common/MemsetFast.inl index 5af6f5486e..8e1f3d4c5a 100644 --- a/common/MemsetFast.inl +++ b/common/MemsetFast.inl @@ -18,74 +18,78 @@ #include template -__noinline void memset_sse_a(void *dest, const size_t size) +__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) { - case 0x07: - _mm_store_ps(&destxmm[0x07 - 1][0], srcreg); - // Fall through - case 0x06: - _mm_store_ps(&destxmm[0x06 - 1][0], srcreg); - // Fall through - case 0x05: - _mm_store_ps(&destxmm[0x05 - 1][0], srcreg); - // Fall through - case 0x04: - _mm_store_ps(&destxmm[0x04 - 1][0], srcreg); - // Fall through - case 0x03: - _mm_store_ps(&destxmm[0x03 - 1][0], srcreg); - // Fall through - case 0x02: - _mm_store_ps(&destxmm[0x02 - 1][0], srcreg); - // Fall through - case 0x01: - _mm_store_ps(&destxmm[0x01 - 1][0], srcreg); - // Fall through - } + switch (MZFqwc & 0x07) + { + case 0x07: + _mm_store_ps(&destxmm[0x07 - 1][0], srcreg); + // Fall through + case 0x06: + _mm_store_ps(&destxmm[0x06 - 1][0], srcreg); + // Fall through + case 0x05: + _mm_store_ps(&destxmm[0x05 - 1][0], srcreg); + // Fall through + case 0x04: + _mm_store_ps(&destxmm[0x04 - 1][0], srcreg); + // Fall through + case 0x03: + _mm_store_ps(&destxmm[0x03 - 1][0], srcreg); + // Fall through + case 0x02: + _mm_store_ps(&destxmm[0x02 - 1][0], srcreg); + // Fall through + case 0x01: + _mm_store_ps(&destxmm[0x01 - 1][0], srcreg); + // Fall through + } - 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); } template -__noinline void memset_sse_a(T &dest) +__noinline void memset_sse_a(T& dest) { - static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset"); - memset_sse_a(&dest, sizeof(dest)); + static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset"); + memset_sse_a(&dest, sizeof(dest)); } template -void memzero_sse_a(T &dest) +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)); } diff --git a/common/Mutex.cpp b/common/Mutex.cpp index 8736f0dd60..25925b90b0 100644 --- a/common/Mutex.cpp +++ b/common/Mutex.cpp @@ -20,9 +20,9 @@ namespace Threading { -static std::atomic _attr_refcount(0); -static pthread_mutexattr_t _attr_recursive; -} + static std::atomic _attr_refcount(0); + static pthread_mutexattr_t _attr_recursive; +} // namespace Threading // -------------------------------------------------------------------------------------- // Mutex Implementations @@ -52,90 +52,94 @@ static pthread_mutexattr_t _attr_recursive; // 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) { - // check if the timeout has expired, gettimeofday() is implemented - // efficiently (in userspace) on OSX - struct timeval now; - gettimeofday(&now, NULL); - if (now.tv_sec > abs_timeout->tv_sec - || (now.tv_sec == abs_timeout->tv_sec - && (u64)now.tv_usec * 1000ULL > (u64)abs_timeout->tv_nsec)) { - return ETIMEDOUT; - } + while ((err = pthread_mutex_trylock(mutex)) == EBUSY) + { + // check if the timeout has expired, gettimeofday() is implemented + // efficiently (in userspace) on OSX + struct timeval now; + gettimeofday(&now, NULL); + if (now.tv_sec > abs_timeout->tv_sec || (now.tv_sec == abs_timeout->tv_sec && (u64)now.tv_usec * 1000ULL > (u64)abs_timeout->tv_nsec)) + { + return ETIMEDOUT; + } - // acquiring lock failed, sleep some - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = TIMEDLOCK_EMU_SLEEP_NS; - while (nanosleep(&ts, &ts) == -1); - } + // acquiring lock failed, sleep some + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = TIMEDLOCK_EMU_SLEEP_NS; + while (nanosleep(&ts, &ts) == -1) + ; + } - 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); 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() { - try { - Mutex::Detach(); - } - DESTRUCTOR_CATCHALL; + try + { + Mutex::Detach(); + } + DESTRUCTOR_CATCHALL; } Threading::MutexRecursive::MutexRecursive() - : Mutex(false) + : 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() { - 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() // 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,11 +157,12 @@ 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; } @@ -167,25 +172,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 @@ -194,45 +199,56 @@ 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 } @@ -245,14 +261,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. @@ -262,22 +278,24 @@ 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; } // -------------------------------------------------------------------------------------- @@ -286,72 +304,72 @@ bool Threading::Mutex::WaitWithoutYield(const wxTimeSpan &timeout) Threading::ScopedLock::~ScopedLock() { - 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(locker); - if (!m_lock) - return; + m_lock = const_cast(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(&locker); + m_lock = const_cast(&locker); } -void Threading::ScopedLock::Assign(const Mutex *locker) +void Threading::ScopedLock::Assign(const Mutex* locker) { - m_lock = const_cast(locker); + m_lock = const_cast(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(&locker); - if (!m_lock) - return; - m_IsLocked = isTryLock ? m_lock->TryAcquire() : false; + m_lock = const_cast(&locker); + if (!m_lock) + return; + m_IsLocked = isTryLock ? m_lock->TryAcquire() : false; } diff --git a/common/PageFaultSource.h b/common/PageFaultSource.h index 4e530dbbb3..5f055cd386 100644 --- a/common/PageFaultSource.h +++ b/common/PageFaultSource.h @@ -30,12 +30,12 @@ struct PageFaultInfo { - uptr addr; + uptr addr; - PageFaultInfo(uptr address) - { - addr = address; - } + PageFaultInfo(uptr address) + { + addr = address; + } }; // -------------------------------------------------------------------------------------- @@ -44,22 +44,22 @@ struct PageFaultInfo class IEventListener_PageFault : public IEventDispatcher { public: - typedef PageFaultInfo EvtParams; + typedef PageFaultInfo EvtParams; public: - virtual ~IEventListener_PageFault() = default; + virtual ~IEventListener_PageFault() = default; - 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) {} }; // -------------------------------------------------------------------------------------- @@ -68,34 +68,34 @@ public: class EventListener_PageFault : public IEventListener_PageFault { public: - EventListener_PageFault(); - virtual ~EventListener_PageFault(); + EventListener_PageFault(); + virtual ~EventListener_PageFault(); }; template 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() = default; + virtual ~EventListenerHelper_PageFault() = default; 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); + } }; // -------------------------------------------------------------------------------------- @@ -104,23 +104,23 @@ protected: class SrcType_PageFault : public EventSource { protected: - typedef EventSource _parent; + typedef EventSource _parent; protected: - bool m_handled; + bool m_handled; public: - SrcType_PageFault() - : m_handled(false) - { - } - virtual ~SrcType_PageFault() = default; + SrcType_PageFault() + : m_handled(false) + { + } + virtual ~SrcType_PageFault() = default; - bool WasHandled() const { return m_handled; } - virtual void Dispatch(const PageFaultInfo ¶ms); + 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); }; @@ -130,40 +130,41 @@ protected: // -------------------------------------------------------------------------------------- class VirtualMemoryManager { - DeclareNoncopyableObject(VirtualMemoryManager); + DeclareNoncopyableObject(VirtualMemoryManager); - wxString m_name; + wxString m_name; - uptr m_baseptr; + uptr m_baseptr; - // An array to track page usage (to trigger asserts if things try to overlap) - std::atomic *m_pageuse; + // An array to track page usage (to trigger asserts if things try to overlap) + std::atomic* m_pageuse; - // reserved memory (in pages) - u32 m_pages_reserved; + // reserved memory (in pages) + u32 m_pages_reserved; public: - // If upper_bounds is nonzero and the OS fails to allocate memory that is below it, - // calls to IsOk() will return false and Alloc() will always return null pointers - // strict indicates that the allocation should quietly fail if the memory can't be mapped at `base` - VirtualMemoryManager(const wxString &name, uptr base, size_t size, uptr upper_bounds = 0, bool strict = false); - ~VirtualMemoryManager(); + // If upper_bounds is nonzero and the OS fails to allocate memory that is below it, + // calls to IsOk() will return false and Alloc() will always return null pointers + // strict indicates that the allocation should quietly fail if the memory can't be mapped at `base` + VirtualMemoryManager(const wxString& name, uptr base, size_t size, uptr upper_bounds = 0, bool strict = false); + ~VirtualMemoryManager(); - void *GetBase() const { return (void *)m_baseptr; } + void* GetBase() const { return (void*)m_baseptr; } - // Request the use of the memory at offsetLocation bytes from the start of the reserved memory area - // offsetLocation must be page-aligned - void *Alloc(uptr offsetLocation, size_t size) const; + // Request the use of the memory at offsetLocation bytes from the start of the reserved memory area + // offsetLocation must be page-aligned + void* Alloc(uptr offsetLocation, size_t size) const; - void *AllocAtAddress(void *address, size_t size) const { - return Alloc(size, (uptr)address - m_baseptr); - } + void* AllocAtAddress(void* address, size_t size) const + { + return Alloc(size, (uptr)address - m_baseptr); + } - void Free(void *address, size_t size) const; + void Free(void* address, size_t size) const; - // Was this VirtualMemoryManager successfully able to get its memory mapping? - // (If not, calls to Alloc will return null pointers) - bool IsOk() const { return m_baseptr != 0; } + // Was this VirtualMemoryManager successfully able to get its memory mapping? + // (If not, calls to Alloc will return null pointers) + bool IsOk() const { return m_baseptr != 0; } }; typedef std::shared_ptr VirtualMemoryManagerPtr; @@ -173,13 +174,14 @@ typedef std::shared_ptr VirtualMemoryManagerPtr; // -------------------------------------------------------------------------------------- class VirtualMemoryBumpAllocator { - const VirtualMemoryManagerPtr m_allocator; - std::atomic m_baseptr{0}; - const uptr m_endptr = 0; + const VirtualMemoryManagerPtr m_allocator; + std::atomic m_baseptr{0}; + const uptr m_endptr = 0; + public: - VirtualMemoryBumpAllocator(VirtualMemoryManagerPtr allocator, size_t size, uptr offsetLocation); - void *Alloc(size_t size); - const VirtualMemoryManagerPtr& GetAllocator() { return m_allocator; } + VirtualMemoryBumpAllocator(VirtualMemoryManagerPtr allocator, size_t size, uptr offsetLocation); + void* Alloc(size_t size); + const VirtualMemoryManagerPtr& GetAllocator() { return m_allocator; } }; // -------------------------------------------------------------------------------------- @@ -187,108 +189,108 @@ public: // -------------------------------------------------------------------------------------- class VirtualMemoryReserve { - DeclareNoncopyableObject(VirtualMemoryReserve); + DeclareNoncopyableObject(VirtualMemoryReserve); protected: - wxString m_name; + wxString m_name; - // Where the memory came from (so we can return it) - VirtualMemoryManagerPtr m_allocator; + // Where the memory came from (so we can return it) + VirtualMemoryManagerPtr m_allocator; - // 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; + // 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; + // 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; - // Allows the implementation to decide how much memory it needs to allocate if someone requests the given size - // Should translate requests of size 0 to m_defsize - virtual size_t GetSize(size_t requestedSize); + // Allows the implementation to decide how much memory it needs to allocate if someone requests the given size + // Should translate requests of size 0 to m_defsize + virtual size_t GetSize(size_t requestedSize); public: - VirtualMemoryReserve(const wxString &name, size_t size = 0); - virtual ~VirtualMemoryReserve() - { - Release(); - } + VirtualMemoryReserve(const wxString& name, size_t size = 0); + virtual ~VirtualMemoryReserve() + { + Release(); + } - // Initialize with the given piece of memory - // Note: The memory is already allocated, the allocator is for future use to free the region - // It may be null in which case there is no way to free the memory in a way it will be usable again - virtual void *Assign(VirtualMemoryManagerPtr allocator, void *baseptr, size_t size); + // Initialize with the given piece of memory + // Note: The memory is already allocated, the allocator is for future use to free the region + // It may be null in which case there is no way to free the memory in a way it will be usable again + virtual void* Assign(VirtualMemoryManagerPtr allocator, void* baseptr, size_t size); - void *Reserve(VirtualMemoryManagerPtr allocator, uptr baseOffset, size_t size = 0) - { - size = GetSize(size); - void *allocation = allocator->Alloc(baseOffset, size); - return Assign(std::move(allocator), allocation, size); - } - void *Reserve(VirtualMemoryBumpAllocator& allocator, size_t size = 0) - { - size = GetSize(size); - return Assign(allocator.GetAllocator(), allocator.Alloc(size), size); - } + void* Reserve(VirtualMemoryManagerPtr allocator, uptr baseOffset, size_t size = 0) + { + size = GetSize(size); + void* allocation = allocator->Alloc(baseOffset, size); + return Assign(std::move(allocator), allocation, size); + } + void* Reserve(VirtualMemoryBumpAllocator& allocator, size_t size = 0) + { + size = GetSize(size); + return Assign(allocator.GetAllocator(), allocator.Alloc(size), size); + } - virtual void Reset(); - virtual void Release(); - virtual bool TryResize(uint newsize); - virtual bool Commit(); + virtual void Reset(); + virtual void Release(); + virtual bool TryResize(uint newsize); + virtual bool Commit(); - virtual void ForbidModification(); - virtual void AllowModification(); + virtual void ForbidModification(); + virtual void AllowModification(); - bool IsOk() const { return m_baseptr != NULL; } - const wxString& GetName() const { return m_name; } + bool IsOk() const { return m_baseptr != NULL; } + const wxString& GetName() const { return m_name; } - 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; } + 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; } - 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); } + 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); } - VirtualMemoryReserve &SetPageAccessOnCommit(const PageProtectionMode &mode); + VirtualMemoryReserve& SetPageAccessOnCommit(const PageProtectionMode& mode); - 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; } - u8 &operator[](uint idx) - { - 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); - } + 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); }; #ifdef __POSIX__ @@ -299,11 +301,11 @@ protected: #elif defined(_WIN32) struct _EXCEPTION_POINTERS; -extern long __stdcall SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS *eps); +extern long __stdcall SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS* eps); #define PCSX2_PAGEFAULT_PROTECT __try #define PCSX2_PAGEFAULT_EXCEPT \ - __except (SysPageFaultExceptionFilter(GetExceptionInformation())) {} + __except (SysPageFaultExceptionFilter(GetExceptionInformation())) {} #else #error PCSX2 - Unsupported operating system platform. @@ -313,5 +315,5 @@ extern void pxInstallSignalHandler(); extern void _platform_InstallSignalHandler(); #include "Threading.h" -extern SrcType_PageFault *Source_PageFault; +extern SrcType_PageFault* Source_PageFault; extern Threading::Mutex PageFault_Mutex; diff --git a/common/Path.h b/common/Path.h index 337068c189..cd0f4cd2ce 100644 --- a/common/Path.h +++ b/common/Path.h @@ -26,180 +26,184 @@ 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; } }; // -------------------------------------------------------------------------------------- @@ -211,20 +215,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); +} // namespace Path diff --git a/common/PathUtils.cpp b/common/PathUtils.cpp index 542c3acdcf..dd6f0328e3 100644 --- a/common/PathUtils.cpp +++ b/common/PathUtils.cpp @@ -22,60 +22,60 @@ // 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() @@ -87,9 +87,9 @@ bool wxDirName::Mkdir() #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); } @@ -98,111 +98,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) +void pxLaunch(const char* filename) { - pxLaunch(fromUTF8(filename)); + pxLaunch(fromUTF8(filename)); } // ------------------------------------------------------------------------ @@ -211,12 +211,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) +void pxExplore(const char* path) { - pxExplore(fromUTF8(path)); + pxExplore(fromUTF8(path)); } diff --git a/common/Pcsx2Types.h b/common/Pcsx2Types.h index 606c94d719..44ed2e60c5 100644 --- a/common/Pcsx2Types.h +++ b/common/Pcsx2Types.h @@ -60,116 +60,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]; } + 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); + } - 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; + // 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; + 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 diff --git a/common/Perf.cpp b/common/Perf.cpp index bd67c3ef47..6007ceabae 100644 --- a/common/Perf.cpp +++ b/common/Perf.cpp @@ -33,174 +33,175 @@ namespace Perf { -// Warning object aren't thread safe -InfoVector any(""); -InfoVector ee("EE"); -InfoVector iop("IOP"); -InfoVector vu("VU"); -InfoVector vif("VIF"); + // Warning object aren't thread safe + InfoVector any(""); + InfoVector ee("EE"); + InfoVector iop("IOP"); + InfoVector vu("VU"); + InfoVector vif("VIF"); // Perf is only supported on linux #if defined(__linux__) && (defined(ProfileWithPerf) || defined(ENABLE_VTUNE)) -//////////////////////////////////////////////////////////////////////////////// -// 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)); #ifdef ENABLE_VTUNE - m_vtune_id = iJIT_GetNewMethodID(); + m_vtune_id = iJIT_GetNewMethodID(); #else - m_vtune_id = 0; + m_vtune_id = 0; #endif -} + } -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) -{ + 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 #if defined(ENABLE_VTUNE) || !defined(MERGE_BLOCK_RESULT) - u32 max_code_size = 16 * _1kb; + u32 max_code_size = 16 * _1kb; #else - u32 max_code_size = _1gb; + u32 max_code_size = _1gb; #endif - if (size < max_code_size) { - m_v.emplace_back(x86, size, symbol); + if (size < max_code_size) + { + m_v.emplace_back(x86, size, symbol); #ifdef ENABLE_VTUNE - std::string name = std::string(symbol); + std::string name = std::string(symbol); - iJIT_Method_Load ml; + iJIT_Method_Load ml; - memset(&ml, 0, sizeof(ml)); + memset(&ml, 0, sizeof(ml)); - ml.method_id = iJIT_GetNewMethodID(); - ml.method_name = (char *)name.c_str(); - ml.method_load_address = (void *)x86; - ml.method_size = size; + ml.method_id = iJIT_GetNewMethodID(); + ml.method_name = (char*)name.c_str(); + ml.method_load_address = (void*)x86; + ml.method_size = size; - iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &ml); + iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &ml); //fprintf(stderr, "mapF %s: %p size %dKB\n", ml.method_name, ml.method_load_address, ml.method_size / 1024u); #endif - } -} + } + } -void InfoVector::map(uptr x86, u32 size, u32 pc) -{ + void InfoVector::map(uptr x86, u32 size, u32 pc) + { #ifndef MERGE_BLOCK_RESULT - m_v.emplace_back(x86, size, m_prefix, pc); + m_v.emplace_back(x86, size, m_prefix, pc); #endif #ifdef ENABLE_VTUNE - iJIT_Method_Load_V2 ml; + iJIT_Method_Load_V2 ml; - memset(&ml, 0, sizeof(ml)); + memset(&ml, 0, sizeof(ml)); #ifdef MERGE_BLOCK_RESULT - ml.method_id = m_vtune_id; - ml.method_name = m_prefix; + ml.method_id = m_vtune_id; + ml.method_name = m_prefix; #else - std::string name = std::string(m_prefix) + "_" + std::to_string(pc); - ml.method_id = iJIT_GetNewMethodID(); - ml.method_name = (char *)name.c_str(); + std::string name = std::string(m_prefix) + "_" + std::to_string(pc); + ml.method_id = iJIT_GetNewMethodID(); + ml.method_name = (char*)name.c_str(); #endif - ml.method_load_address = (void *)x86; - ml.method_size = size; + ml.method_load_address = (void*)x86; + ml.method_size = size; - iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2, &ml); + iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2, &ml); //fprintf(stderr, "mapB %s: %p size %d\n", ml.method_name, ml.method_load_address, ml.method_size); #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()); -} + 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 -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + // Global function + //////////////////////////////////////////////////////////////////////////////// -void dump() -{ - char file[256]; - snprintf(file, 250, "/tmp/perf-%d.map", getpid()); - FILE *fp = fopen(file, "w"); + 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); + any.print(fp); + ee.print(fp); + iop.print(fp); + vu.print(fp); - if (fp) - fclose(fp); -} + if (fp) + fclose(fp); + } -void dump_and_reset() -{ - dump(); + void dump_and_reset() + { + dump(); - any.reset(); - ee.reset(); - iop.reset(); - vu.reset(); -} + any.reset(); + ee.reset(); + iop.reset(); + vu.reset(); + } #else -//////////////////////////////////////////////////////////////////////////////// -// Dummy implementation -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + // Dummy implementation + //////////////////////////////////////////////////////////////////////////////// -InfoVector::InfoVector(const char *prefix) - : m_vtune_id(0) -{ -} -void InfoVector::map(uptr x86, u32 size, const char *symbol) {} -void InfoVector::map(uptr x86, u32 size, u32 pc) {} -void InfoVector::reset() {} + InfoVector::InfoVector(const char* prefix) + : m_vtune_id(0) + { + } + 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() {} + void dump() {} + void dump_and_reset() {} #endif -} +} // namespace Perf diff --git a/common/Perf.h b/common/Perf.h index c3b96ef892..57324aefc7 100644 --- a/common/Perf.h +++ b/common/Perf.h @@ -22,41 +22,41 @@ 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 m_v; - char m_prefix[20]; - unsigned int m_vtune_id; + class InfoVector + { + std::vector m_v; + char m_prefix[20]; + unsigned int m_vtune_id; -public: - InfoVector(const char *prefix); + public: + 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 vif; -} + extern InfoVector any; + extern InfoVector ee; + extern InfoVector iop; + extern InfoVector vu; + extern InfoVector vif; +} // namespace Perf diff --git a/common/PersistentThread.h b/common/PersistentThread.h index 320cd0928f..ce7ca56e56 100644 --- a/common/PersistentThread.h +++ b/common/PersistentThread.h @@ -22,188 +22,188 @@ namespace Threading { -// -------------------------------------------------------------------------------------- -// ThreadDeleteEvent -// -------------------------------------------------------------------------------------- -class EventListener_Thread : public IEventDispatcher -{ -public: - typedef int EvtParams; + // -------------------------------------------------------------------------------------- + // ThreadDeleteEvent + // -------------------------------------------------------------------------------------- + class EventListener_Thread : public IEventDispatcher + { + 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() = default; + virtual ~EventListener_Thread() = default; - 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 ¶ms) - { - 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; + }; -/// Set the name of the current thread -void SetNameOfCurrentThread(const char* name); + /// Set the name of the current thread + void SetNameOfCurrentThread(const char* name); -// -------------------------------------------------------------------------------------- -// pxThread - Helper class for the basics of starting/managing persistent threads. -// -------------------------------------------------------------------------------------- -// This class is meant to be a helper for the typical threading model of "start once and -// reuse many times." This class incorporates a lot of extra overhead in stopping and -// starting threads, but in turn provides most of the basic thread-safety and event-handling -// functionality needed for a threaded operation. In practice this model is usually an -// ideal one for efficiency since Operating Systems themselves typically subscribe to a -// design where sleeping, suspending, and resuming threads is very efficient, but starting -// new threads has quite a bit of overhead. -// -// To use this as a base class for your threaded procedure, overload the following virtual -// methods: -// void OnStart(); -// void ExecuteTaskInThread(); -// void OnCleanupInThread(); -// -// Use the public methods Start() and Cancel() to start and shutdown the thread, and use -// m_sem_event internally to post/receive events for the thread (make a public accessor for -// it in your derived class if your thread utilizes the post). -// -// Notes: -// * Constructing threads as static global vars isn't recommended since it can potentially -// confuse w32pthreads, if the static initializers are executed out-of-order (C++ offers -// no dependency options for ensuring correct static var initializations). Use heap -// allocation to create thread objects instead. -// -class pxThread -{ - DeclareNoncopyableObject(pxThread); + // -------------------------------------------------------------------------------------- + // pxThread - Helper class for the basics of starting/managing persistent threads. + // -------------------------------------------------------------------------------------- + // This class is meant to be a helper for the typical threading model of "start once and + // reuse many times." This class incorporates a lot of extra overhead in stopping and + // starting threads, but in turn provides most of the basic thread-safety and event-handling + // functionality needed for a threaded operation. In practice this model is usually an + // ideal one for efficiency since Operating Systems themselves typically subscribe to a + // design where sleeping, suspending, and resuming threads is very efficient, but starting + // new threads has quite a bit of overhead. + // + // To use this as a base class for your threaded procedure, overload the following virtual + // methods: + // void OnStart(); + // void ExecuteTaskInThread(); + // void OnCleanupInThread(); + // + // Use the public methods Start() and Cancel() to start and shutdown the thread, and use + // m_sem_event internally to post/receive events for the thread (make a public accessor for + // it in your derived class if your thread utilizes the post). + // + // Notes: + // * Constructing threads as static global vars isn't recommended since it can potentially + // confuse w32pthreads, if the static initializers are executed out-of-order (C++ offers + // no dependency options for ensuring correct static var initializations). Use heap + // allocation to create thread objects instead. + // + 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 m_detached; // a boolean value which indicates if the m_thread handle is valid - std::atomic m_running; // set true by Start(), and set false by Cancel(), Block(), etc. + std::atomic m_detached; // a boolean value which indicates if the m_thread handle is valid + std::atomic 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 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 m_except; - EventSource m_evtsrc_OnDelete; + EventSource m_evtsrc_OnDelete; -public: - virtual ~pxThread(); - pxThread(const wxString &name = L"pxThread"); + public: + virtual ~pxThread(); + 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) { SetNameOfCurrentThread(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) { SetNameOfCurrentThread(name); } + void _internal_execute(); + void _try_virtual_invoke(void (pxThread::*method)()); + void _ThreadCleanup(); - static void *_internal_callback(void *func); - static void internal_callback_helper(void *func); - static void _pt_callback_cleanup(void *handle); -}; -} + static void* _internal_callback(void* func); + static void internal_callback_helper(void* func); + static void _pt_callback_cleanup(void* handle); + }; +} // namespace Threading diff --git a/common/RwMutex.cpp b/common/RwMutex.cpp index 7241f46c29..1118378ab4 100644 --- a/common/RwMutex.cpp +++ b/common/RwMutex.cpp @@ -20,37 +20,37 @@ // -------------------------------------------------------------------------------------- Threading::RwMutex::RwMutex() { - pthread_rwlock_init(&m_rwlock, NULL); + pthread_rwlock_init(&m_rwlock, NULL); } Threading::RwMutex::~RwMutex() { - pthread_rwlock_destroy(&m_rwlock); + pthread_rwlock_destroy(&m_rwlock); } void Threading::RwMutex::AcquireRead() { - pthread_rwlock_rdlock(&m_rwlock); + pthread_rwlock_rdlock(&m_rwlock); } void Threading::RwMutex::AcquireWrite() { - pthread_rwlock_wrlock(&m_rwlock); + pthread_rwlock_wrlock(&m_rwlock); } bool Threading::RwMutex::TryAcquireRead() { - return pthread_rwlock_tryrdlock(&m_rwlock) != EBUSY; + return pthread_rwlock_tryrdlock(&m_rwlock) != EBUSY; } bool Threading::RwMutex::TryAcquireWrite() { - return pthread_rwlock_trywrlock(&m_rwlock) != EBUSY; + return pthread_rwlock_trywrlock(&m_rwlock) != EBUSY; } void Threading::RwMutex::Release() { - pthread_rwlock_unlock(&m_rwlock); + pthread_rwlock_unlock(&m_rwlock); } // -------------------------------------------------------------------------------------- @@ -58,57 +58,57 @@ void Threading::RwMutex::Release() // -------------------------------------------------------------------------------------- Threading::BaseScopedReadWriteLock::~BaseScopedReadWriteLock() { - if (m_IsLocked) - m_lock.Release(); + if (m_IsLocked) + m_lock.Release(); } // Provides manual unlocking of a scoped lock prior to object destruction. void Threading::BaseScopedReadWriteLock::Release() { - if (!m_IsLocked) - return; - m_IsLocked = false; - m_lock.Release(); + if (!m_IsLocked) + return; + m_IsLocked = false; + m_lock.Release(); } // -------------------------------------------------------------------------------------- // ScopedReadLock / ScopedWriteLock // -------------------------------------------------------------------------------------- -Threading::ScopedReadLock::ScopedReadLock(RwMutex &locker) - : BaseScopedReadWriteLock(locker) +Threading::ScopedReadLock::ScopedReadLock(RwMutex& locker) + : BaseScopedReadWriteLock(locker) { - m_IsLocked = true; - m_lock.AcquireRead(); + m_IsLocked = true; + m_lock.AcquireRead(); } // provides manual locking of a scoped lock, to re-lock after a manual unlocking. void Threading::ScopedReadLock::Acquire() { - if (m_IsLocked) - return; - m_lock.AcquireRead(); - m_IsLocked = true; + if (m_IsLocked) + return; + m_lock.AcquireRead(); + m_IsLocked = true; } -Threading::ScopedWriteLock::ScopedWriteLock(RwMutex &locker) - : BaseScopedReadWriteLock(locker) +Threading::ScopedWriteLock::ScopedWriteLock(RwMutex& locker) + : BaseScopedReadWriteLock(locker) { - m_IsLocked = true; - m_lock.AcquireWrite(); + m_IsLocked = true; + m_lock.AcquireWrite(); } // provides manual locking of a scoped lock, to re-lock after a manual unlocking. void Threading::ScopedWriteLock::Acquire() { - if (m_IsLocked) - return; - m_lock.AcquireWrite(); - m_IsLocked = true; + if (m_IsLocked) + return; + m_lock.AcquireWrite(); + m_IsLocked = true; } // Special constructor used by ScopedTryLock -Threading::ScopedWriteLock::ScopedWriteLock(RwMutex &locker, bool isTryLock) - : BaseScopedReadWriteLock(locker) +Threading::ScopedWriteLock::ScopedWriteLock(RwMutex& locker, bool isTryLock) + : BaseScopedReadWriteLock(locker) { - //m_IsLocked = isTryLock ? m_lock.TryAcquireWrite() : false; + //m_IsLocked = isTryLock ? m_lock.TryAcquireWrite() : false; } diff --git a/common/RwMutex.h b/common/RwMutex.h index 3028022a14..a3006e5a3a 100644 --- a/common/RwMutex.h +++ b/common/RwMutex.h @@ -19,72 +19,72 @@ namespace Threading { -// -------------------------------------------------------------------------------------- -// RwMutex -// -------------------------------------------------------------------------------------- -class RwMutex -{ - DeclareNoncopyableObject(RwMutex); + // -------------------------------------------------------------------------------------- + // RwMutex + // -------------------------------------------------------------------------------------- + class RwMutex + { + DeclareNoncopyableObject(RwMutex); -protected: - pthread_rwlock_t m_rwlock; + protected: + pthread_rwlock_t m_rwlock; -public: - RwMutex(); - virtual ~RwMutex(); + public: + RwMutex(); + virtual ~RwMutex(); - virtual void AcquireRead(); - virtual void AcquireWrite(); - virtual bool TryAcquireRead(); - virtual bool TryAcquireWrite(); + virtual void AcquireRead(); + virtual void AcquireWrite(); + virtual bool TryAcquireRead(); + virtual bool TryAcquireWrite(); - virtual void Release(); -}; + virtual void Release(); + }; -// -------------------------------------------------------------------------------------- -// BaseScopedReadWriteLock -// -------------------------------------------------------------------------------------- -class BaseScopedReadWriteLock -{ - DeclareNoncopyableObject(BaseScopedReadWriteLock); + // -------------------------------------------------------------------------------------- + // 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(); + virtual ~BaseScopedReadWriteLock(); - 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() = default; + // -------------------------------------------------------------------------------------- + // ScopedReadLock / ScopedWriteLock + // -------------------------------------------------------------------------------------- + class ScopedReadLock : public BaseScopedReadWriteLock + { + public: + ScopedReadLock(RwMutex& locker); + virtual ~ScopedReadLock() = default; - void Acquire(); -}; + void Acquire(); + }; -class ScopedWriteLock : public BaseScopedReadWriteLock -{ -public: - ScopedWriteLock(RwMutex &locker); - virtual ~ScopedWriteLock() = default; + class ScopedWriteLock : public BaseScopedReadWriteLock + { + public: + ScopedWriteLock(RwMutex& locker); + virtual ~ScopedWriteLock() = default; - void Acquire(); + void Acquire(); -protected: - ScopedWriteLock(RwMutex &locker, bool isTryLock); -}; -} + protected: + ScopedWriteLock(RwMutex& locker, bool isTryLock); + }; +} // namespace Threading diff --git a/common/SafeArray.h b/common/SafeArray.h index 007dfca162..cf6641590d 100644 --- a/common/SafeArray.h +++ b/common/SafeArray.h @@ -26,7 +26,7 @@ // Microsoft Windows only macro, useful for freeing out COM objects: #define safe_release(ptr) \ - ((void)((((ptr) != NULL) && ((ptr)->Release(), !!0)), (ptr) = NULL)) + ((void)((((ptr) != NULL) && ((ptr)->Release(), !!0)), (ptr) = NULL)) // -------------------------------------------------------------------------------------- // SafeArray @@ -37,72 +37,72 @@ template 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(); + virtual ~SafeArray(); - explicit SafeArray(const wxChar *name = L"Unnamed"); - explicit SafeArray(int initialSize, const wxChar *name = L"Unnamed"); + 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); - } + void Dispose(); + void ExactAlloc(int newsize); + void MakeRoomFor(int newsize) + { + if (newsize > m_size) + ExactAlloc(newsize); + } - bool IsDisposed() const { return (m_ptr == NULL); } + bool IsDisposed() const { return (m_ptr == NULL); } - // 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); } + // 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); } - // Extends the containment area of the array. Extensions are performed - // in chunks. - void GrowBy(int items) - { - MakeRoomFor(m_size + ChunkSize + items + 1); - } + // 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 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 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 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 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 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); } - virtual SafeArray *Clone() const; + virtual SafeArray* Clone() const; }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -118,73 +118,73 @@ public: template 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(); - explicit SafeList(const wxChar *name = L"Unnamed"); - explicit SafeList(int initialSize, const wxChar *name = L"Unnamed"); - virtual SafeList *Clone() const; + virtual ~SafeList(); + explicit SafeList(const wxChar* name = L"Unnamed"); + explicit SafeList(int initialSize, const wxChar* name = L"Unnamed"); + virtual SafeList* 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]; } }; // -------------------------------------------------------------------------------------- @@ -197,21 +197,21 @@ public: template class SafeAlignedArray : public SafeArray { - typedef SafeArray _parent; + typedef SafeArray _parent; protected: - T *_virtual_realloc(int newsize); + T* _virtual_realloc(int newsize); public: - using _parent::operator[]; + using _parent::operator[]; - virtual ~SafeAlignedArray(); + virtual ~SafeAlignedArray(); - explicit SafeAlignedArray(const wxChar *name = L"Unnamed") - : SafeArray::SafeArray(name) - { - } + explicit SafeAlignedArray(const wxChar* name = L"Unnamed") + : SafeArray::SafeArray(name) + { + } - explicit SafeAlignedArray(int initialSize, const wxChar *name = L"Unnamed"); - virtual SafeAlignedArray *Clone() const; + explicit SafeAlignedArray(int initialSize, const wxChar* name = L"Unnamed"); + virtual SafeAlignedArray* Clone() const; }; diff --git a/common/SafeArray.inl b/common/SafeArray.inl index 5407a00ced..05c827eb34 100644 --- a/common/SafeArray.inl +++ b/common/SafeArray.inl @@ -23,79 +23,80 @@ // Throws: // Exception::OutOfMemory if the allocated_mem pointer is NULL. template -SafeArray::SafeArray(const wxChar *name, T *allocated_mem, int initSize) - : Name(name) +SafeArray::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 -T *SafeArray::_virtual_realloc(int newsize) +T* SafeArray::_virtual_realloc(int newsize) { - T *retval = (T *)((m_ptr == NULL) ? - malloc(newsize * sizeof(T)) : - realloc(m_ptr, newsize * sizeof(T))); + 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 + 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; - } + u32* fill = (u32*)&retval[m_size]; + const u32* end = (u32*)((((uptr)&retval[newsize - 1]) - 3) & ~0x3); + for (; fill < end; ++fill) + *fill = 0xbaadf00d; + } - return retval; + return retval; } template SafeArray::~SafeArray() { - safe_free(m_ptr); + safe_free(m_ptr); } template -SafeArray::SafeArray(const wxChar *name) - : Name(name) +SafeArray::SafeArray(const wxChar* name) + : Name(name) { - ChunkSize = DefaultChunkSize; - m_ptr = NULL; - m_size = 0; + ChunkSize = DefaultChunkSize; + m_ptr = NULL; + m_size = 0; } template -SafeArray::SafeArray(int initialSize, const wxChar *name) - : Name(name) +SafeArray::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 void SafeArray::Dispose() { - m_size = 0; - safe_free(m_ptr); + m_size = 0; + safe_free(m_ptr); } template -T *SafeArray::_getPtr(uint i) const +T* SafeArray::_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 @@ -103,23 +104,23 @@ T *SafeArray::_getPtr(uint i) const template void SafeArray::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 -SafeArray *SafeArray::Clone() const +SafeArray* SafeArray::Clone() const { - SafeArray *retval = new SafeArray(m_size); - memcpy(retval->GetPtr(), m_ptr, sizeof(T) * m_size); - return retval; + SafeArray* retval = new SafeArray(m_size); + memcpy(retval->GetPtr(), m_ptr, sizeof(T) * m_size); + return retval; } @@ -128,11 +129,11 @@ SafeArray *SafeArray::Clone() const // -------------------------------------------------------------------------------------- template -T *SafeAlignedArray::_virtual_realloc(int newsize) +T* SafeAlignedArray::_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. @@ -141,25 +142,25 @@ T *SafeAlignedArray::_virtual_realloc(int newsize) template SafeAlignedArray::~SafeAlignedArray() { - 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 -SafeAlignedArray::SafeAlignedArray(int initialSize, const wxChar *name) - : SafeArray::SafeArray( - name, - (T *)_aligned_malloc(initialSize * sizeof(T), Alignment), - initialSize) +SafeAlignedArray::SafeAlignedArray(int initialSize, const wxChar* name) + : SafeArray::SafeArray( + name, + (T*)_aligned_malloc(initialSize * sizeof(T), Alignment), + initialSize) { } template -SafeAlignedArray *SafeAlignedArray::Clone() const +SafeAlignedArray* SafeAlignedArray::Clone() const { - SafeAlignedArray *retval = new SafeAlignedArray(this->m_size); - memcpy(retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size); - return retval; + SafeAlignedArray* retval = new SafeAlignedArray(this->m_size); + memcpy(retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size); + return retval; } // -------------------------------------------------------------------------------------- @@ -167,50 +168,51 @@ SafeAlignedArray *SafeAlignedArray::Clone() const // -------------------------------------------------------------------------------------- template -T *SafeList::_virtual_realloc(int newsize) +T* SafeList::_virtual_realloc(int newsize) { - return (T *)realloc(m_ptr, newsize * sizeof(T)); + return (T*)realloc(m_ptr, newsize * sizeof(T)); } template SafeList::~SafeList() { - safe_free(m_ptr); + safe_free(m_ptr); } template -SafeList::SafeList(const wxChar *name) - : Name(name) +SafeList::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 -SafeList::SafeList(int initialSize, const wxChar *name) - : Name(name) +SafeList::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)); + 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(); - } + for (int i = 0; i < m_allocsize; ++i) + { + new (&m_ptr[i]) T(); + } } template -T *SafeList::_getPtr(uint i) const +T* SafeList::_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 @@ -218,42 +220,44 @@ T *SafeList::_getPtr(uint i) const template void SafeList::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 -T &SafeList::New() +T& SafeList::New() { - _MakeRoomFor_threshold(m_length + 1); - return m_ptr[m_length++]; + _MakeRoomFor_threshold(m_length + 1); + return m_ptr[m_length++]; } template -int SafeList::Add(const T &src) +int SafeList::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 -T &SafeList::AddNew(const T &src) +T& SafeList::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 @@ -262,23 +266,23 @@ T &SafeList::AddNew(const T &src) template void SafeList::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 -SafeList *SafeList::Clone() const +SafeList* SafeList::Clone() const { - SafeList *retval = new SafeList(m_length); - memcpy(retval->m_ptr, m_ptr, sizeof(T) * m_length); - return retval; + SafeList* retval = new SafeList(m_length); + memcpy(retval->m_ptr, m_ptr, sizeof(T) * m_length); + return retval; } template void SafeList::_MakeRoomFor_threshold(int newsize) { - MakeRoomFor(newsize + ChunkSize); + MakeRoomFor(newsize + ChunkSize); } diff --git a/common/ScopedAlloc.h b/common/ScopedAlloc.h index 37b3f26fab..cac692cde4 100644 --- a/common/ScopedAlloc.h +++ b/common/ScopedAlloc.h @@ -28,34 +28,34 @@ // pointer to null after deallocation. #define safe_delete(ptr) \ - ((void)(delete (ptr)), (ptr) = NULL) + ((void)(delete (ptr)), (ptr) = NULL) #define safe_delete_array(ptr) \ - ((void)(delete[](ptr)), (ptr) = NULL) + ((void)(delete[](ptr)), (ptr) = NULL) // 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) + ((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)) + ((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)) + ((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 // -------------------------------------------------------------------------------------- @@ -63,7 +63,7 @@ extern void _aligned_free(void *pmem); // -------------------------------------------------------------------------------------- typedef void FnType_OutOfMemory(uptr blocksize); -typedef FnType_OutOfMemory *Fnptr_OutOfMemory; +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 @@ -93,74 +93,74 @@ template 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() - { - //pxAssert(m_buffer==NULL); - } + virtual ~BaseScopedAlloc() + { + //pxAssert(m_buffer==NULL); + } public: - size_t GetSize() const { return m_size; } - size_t GetLength() const { return m_size; } + 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; + // 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; - // 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; + // 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; - void Free() - { - Alloc(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); - } + // 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); + } - T *GetPtr(uint idx = 0) const - { + T* GetPtr(uint idx = 0) const + { #if pxUSE_SECURE_MALLOC - IndexBoundsAssumeDev("ScopedAlloc", idx, m_size); + IndexBoundsAssumeDev("ScopedAlloc", idx, m_size); #endif - return &m_buffer[idx]; - } + return &m_buffer[idx]; + } - T &operator[](uint idx) - { + T& operator[](uint idx) + { #if pxUSE_SECURE_MALLOC - IndexBoundsAssumeDev("ScopedAlloc", idx, m_size); + IndexBoundsAssumeDev("ScopedAlloc", idx, m_size); #endif - return m_buffer[idx]; - } + return m_buffer[idx]; + } - const T &operator[](uint idx) const - { + const T& operator[](uint idx) const + { #if pxUSE_SECURE_MALLOC - IndexBoundsAssumeDev("ScopedAlloc", idx, m_size); + IndexBoundsAssumeDev("ScopedAlloc", idx, m_size); #endif - return m_buffer[idx]; - } + return m_buffer[idx]; + } }; // -------------------------------------------------------------------------------------- @@ -175,42 +175,42 @@ public: template class ScopedAlloc : public BaseScopedAlloc { - typedef BaseScopedAlloc _parent; + typedef BaseScopedAlloc _parent; public: - ScopedAlloc(size_t size = 0) - : _parent() - { - Alloc(size); - } + ScopedAlloc(size_t size = 0) + : _parent() + { + Alloc(size); + } - virtual ~ScopedAlloc() - { - safe_free(this->m_buffer); - } + virtual ~ScopedAlloc() + { + 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"); - } + if (!this->m_buffer) + throw Exception::OutOfMemory(L"ScopedAlloc::Resize"); + } - using _parent::operator[]; + using _parent::operator[]; }; // -------------------------------------------------------------------------------------- @@ -225,40 +225,40 @@ public: template class ScopedAlignedAlloc : public BaseScopedAlloc { - typedef BaseScopedAlloc _parent; + typedef BaseScopedAlloc _parent; public: - ScopedAlignedAlloc(size_t size = 0) - : _parent() - { - Alloc(size); - } + ScopedAlignedAlloc(size_t size = 0) + : _parent() + { + Alloc(size); + } - virtual ~ScopedAlignedAlloc() - { - safe_aligned_free(this->m_buffer); - } + virtual ~ScopedAlignedAlloc() + { + safe_aligned_free(this->m_buffer); + } - virtual void Alloc(size_t newsize) - { - safe_aligned_free(this->m_buffer); - this->m_size = newsize; - if (!this->m_size) - return; + virtual void Alloc(size_t newsize) + { + safe_aligned_free(this->m_buffer); + this->m_size = newsize; + if (!this->m_size) + return; - this->m_buffer = (T *)_aligned_malloc(this->m_size * sizeof(T), align); - if (!this->m_buffer) - throw Exception::OutOfMemory(L"ScopedAlignedAlloc"); - } + this->m_buffer = (T*)_aligned_malloc(this->m_size * sizeof(T), align); + if (!this->m_buffer) + throw Exception::OutOfMemory(L"ScopedAlignedAlloc"); + } - 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; + 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"); - } + if (!this->m_buffer) + throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize"); + } - using _parent::operator[]; + using _parent::operator[]; }; diff --git a/common/ScopedPtrMT.h b/common/ScopedPtrMT.h index 964ce6739a..e8ed6f4e82 100644 --- a/common/ScopedPtrMT.h +++ b/common/ScopedPtrMT.h @@ -25,91 +25,91 @@ using Threading::ScopedLock; template class ScopedPtrMT { - DeclareNoncopyableObject(ScopedPtrMT); + DeclareNoncopyableObject(ScopedPtrMT); protected: - std::atomic m_ptr; - Threading::Mutex m_mtx; + std::atomic 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() { _Delete_unlocked(); } + ~ScopedPtrMT() { _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() noexcept - { - ScopedLock lock(m_mtx); - _Delete_unlocked(); - } + ScopedPtrMT& Delete() noexcept + { + 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 noexcept - { - return m_ptr.load() == nullptr; - } + bool operator!() const noexcept + { + return m_ptr.load() == nullptr; + } - // Equality - bool operator==(T *pT) const noexcept - { - return m_ptr == pT; - } + // Equality + bool operator==(T* pT) const noexcept + { + return m_ptr == pT; + } - // Inequality - bool operator!=(T *pT) const noexcept - { - return !operator==(pT); - } + // Inequality + bool operator!=(T* pT) const noexcept + { + 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 operator T*() const @@ -133,8 +133,8 @@ public: #endif protected: - void _Delete_unlocked() noexcept - { - delete m_ptr.exchange(nullptr); - } + void _Delete_unlocked() noexcept + { + delete m_ptr.exchange(nullptr); + } }; diff --git a/common/Semaphore.cpp b/common/Semaphore.cpp index fe86497934..ef3ad444da 100644 --- a/common/Semaphore.cpp +++ b/common/Semaphore.cpp @@ -26,49 +26,50 @@ Threading::Semaphore::Semaphore() { - sem_init(&m_sema, false, 0); + sem_init(&m_sema, false, 0); } Threading::Semaphore::~Semaphore() { - sem_destroy(&m_sema); + sem_destroy(&m_sema); } void Threading::Semaphore::Reset() { - sem_destroy(&m_sema); - sem_init(&m_sema, false, 0); + sem_destroy(&m_sema); + sem_init(&m_sema, false, 0); } void Threading::Semaphore::Post() { - sem_post(&m_sema); + sem_post(&m_sema); } void Threading::Semaphore::Post(int multiple) { #if defined(_MSC_VER) - sem_post_multiple(&m_sema, multiple); + sem_post_multiple(&m_sema, multiple); #else - // Only w32pthreads has the post_multiple, but it's easy enough to fake: - while (multiple > 0) { - multiple--; - sem_post(&m_sema); - } + // Only w32pthreads has the post_multiple, but it's easy enough to fake: + while (multiple > 0) + { + multiple--; + sem_post(&m_sema); + } #endif } void Threading::Semaphore::WaitWithoutYield() { - pxAssertMsg(!wxThread::IsMain(), "Unyielding semaphore wait issued from the main/gui thread. Please use Wait() instead."); - sem_wait(&m_sema); + pxAssertMsg(!wxThread::IsMain(), "Unyielding semaphore wait issued from the main/gui thread. Please use Wait() instead."); + sem_wait(&m_sema); } -bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan &timeout) +bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan& timeout) { - wxDateTime megafail(wxDateTime::UNow() + timeout); - const timespec fail = {megafail.GetTicks(), megafail.GetMillisecond() * 1000000}; - return sem_timedwait(&m_sema, &fail) == 0; + wxDateTime megafail(wxDateTime::UNow() + timeout); + const timespec fail = {megafail.GetTicks(), megafail.GetMillisecond() * 1000000}; + return sem_timedwait(&m_sema, &fail) == 0; } @@ -80,18 +81,23 @@ bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan &timeout) void Threading::Semaphore::Wait() { #if wxUSE_GUI - if (!wxThread::IsMain() || (wxTheApp == NULL)) { - sem_wait(&m_sema); - } else if (_WaitGui_RecursionGuard(L"Semaphore::Wait")) { - ScopedBusyCursor hourglass(Cursor_ReallyBusy); - sem_wait(&m_sema); - } else { - //ScopedBusyCursor hourglass( Cursor_KindaBusy ); - while (!WaitWithoutYield(def_yieldgui_interval)) - YieldToMain(); - } + if (!wxThread::IsMain() || (wxTheApp == NULL)) + { + sem_wait(&m_sema); + } + else if (_WaitGui_RecursionGuard(L"Semaphore::Wait")) + { + ScopedBusyCursor hourglass(Cursor_ReallyBusy); + sem_wait(&m_sema); + } + else + { + //ScopedBusyCursor hourglass( Cursor_KindaBusy ); + while (!WaitWithoutYield(def_yieldgui_interval)) + YieldToMain(); + } #else - sem_wait(&m_sema); + sem_wait(&m_sema); #endif } @@ -104,29 +110,35 @@ 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 } @@ -140,26 +152,26 @@ bool Threading::Semaphore::Wait(const wxTimeSpan &timeout) // to do a lot of no-cancel waits in a tight loop worker thread, for example. void Threading::Semaphore::WaitNoCancel() { - int oldstate; - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); - //WaitWithoutYield(); - Wait(); - pthread_setcancelstate(oldstate, NULL); + int oldstate; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); + //WaitWithoutYield(); + 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); - //WaitWithoutYield( timeout ); - Wait(timeout); - pthread_setcancelstate(oldstate, NULL); + int oldstate; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); + //WaitWithoutYield( timeout ); + Wait(timeout); + pthread_setcancelstate(oldstate, NULL); } int Threading::Semaphore::Count() { - int retval; - sem_getvalue(&m_sema, &retval); - return retval; + int retval; + sem_getvalue(&m_sema, &retval); + return retval; } #endif diff --git a/common/StringHelpers.cpp b/common/StringHelpers.cpp index 588eaacf9e..6f3d1a8900 100644 --- a/common/StringHelpers.cpp +++ b/common/StringHelpers.cpp @@ -17,59 +17,59 @@ #include "common/Pcsx2Defs.h" #include "common/StringHelpers.h" -__fi wxString fromUTF8(const char *src) +__fi wxString fromUTF8(const char* src) { - // IMPORTANT: We cannot use wxString::FromUTF8 because it *stupidly* relies on a C++ global instance of - // wxMBConvUTF8(). C++ initializes and destroys these globals at random, so any object constructor or - // destructor that attempts to do logging may crash the app (either during startup or during exit) unless - // we use a LOCAL instance of wxMBConvUTF8(). --air + // IMPORTANT: We cannot use wxString::FromUTF8 because it *stupidly* relies on a C++ global instance of + // wxMBConvUTF8(). C++ initializes and destroys these globals at random, so any object constructor or + // destructor that attempts to do logging may crash the app (either during startup or during exit) unless + // we use a LOCAL instance of wxMBConvUTF8(). --air - // Performance? No worries. wxMBConvUTF8() is virtually free. Initializing a stack copy of the class - // is just as efficient as passing a pointer to a pre-instanced global. (which makes me wonder wh wxWidgets - // uses the stupid globals in the first place!) --air + // Performance? No worries. wxMBConvUTF8() is virtually free. Initializing a stack copy of the class + // is just as efficient as passing a pointer to a pre-instanced global. (which makes me wonder wh wxWidgets + // uses the stupid globals in the first place!) --air - return wxString(src, wxMBConvUTF8()); + return wxString(src, wxMBConvUTF8()); } -__fi wxString fromAscii(const char *src) +__fi wxString fromAscii(const char* src) { - return wxString::FromAscii(src); + return wxString::FromAscii(src); } wxString u128::ToString() const { - return pxsFmt(L"0x%08X.%08X.%08X.%08X", _u32[0], _u32[1], _u32[2], _u32[3]); + return pxsFmt(L"0x%08X.%08X.%08X.%08X", _u32[0], _u32[1], _u32[2], _u32[3]); } wxString u128::ToString64() const { - return pxsFmt(L"0x%08X%08X.%08X%08X", _u32[0], _u32[1], _u32[2], _u32[3]); + return pxsFmt(L"0x%08X%08X.%08X%08X", _u32[0], _u32[1], _u32[2], _u32[3]); } wxString u128::ToString8() const { - FastFormatUnicode result; - result.Write(L"0x%02X.%02X", _u8[0], _u8[1]); - for (uint i = 2; i < 16; i += 2) - result.Write(L".%02X.%02X", _u8[i], _u8[i + 1]); - return result; + FastFormatUnicode result; + result.Write(L"0x%02X.%02X", _u8[0], _u8[1]); + for (uint i = 2; i < 16; i += 2) + result.Write(L".%02X.%02X", _u8[i], _u8[i + 1]); + return result; } -void u128::WriteTo(FastFormatAscii &dest) const +void u128::WriteTo(FastFormatAscii& dest) const { - dest.Write("0x%08X.%08X.%08X.%08X", _u32[0], _u32[1], _u32[2], _u32[3]); + dest.Write("0x%08X.%08X.%08X.%08X", _u32[0], _u32[1], _u32[2], _u32[3]); } -void u128::WriteTo64(FastFormatAscii &dest) const +void u128::WriteTo64(FastFormatAscii& dest) const { - dest.Write("0x%08X%08X.%08X%08X", _u32[0], _u32[1], _u32[2], _u32[3]); + dest.Write("0x%08X%08X.%08X%08X", _u32[0], _u32[1], _u32[2], _u32[3]); } -void u128::WriteTo8(FastFormatAscii &dest) const +void u128::WriteTo8(FastFormatAscii& dest) const { - dest.Write("0x%02X.%02X", _u8[0], _u8[1]); - for (uint i = 2; i < 16; i += 2) - dest.Write(".%02X.%02X", _u8[i], _u8[i + 1]); + dest.Write("0x%02X.%02X", _u8[0], _u8[1]); + for (uint i = 2; i < 16; i += 2) + dest.Write(".%02X.%02X", _u8[i], _u8[i + 1]); } // Splits a string into parts and adds the parts into the given SafeList. @@ -78,11 +78,11 @@ void u128::WriteTo8(FastFormatAscii &dest) const // // Note: wxWidgets 2.9 / 3.0 has a wxSplit function, but we're using 2.8 so I had to make // my own. -void SplitString(wxArrayString &dest, const wxString &src, const wxString &delims, wxStringTokenizerMode mode) +void SplitString(wxArrayString& dest, const wxString& src, const wxString& delims, wxStringTokenizerMode mode) { - wxStringTokenizer parts(src, delims, mode); - while (parts.HasMoreTokens()) - dest.Add(parts.GetNextToken()); + wxStringTokenizer parts(src, delims, mode); + while (parts.HasMoreTokens()) + dest.Add(parts.GetNextToken()); } // Joins a list of strings into one larger string, using the given string concatenation @@ -91,32 +91,34 @@ void SplitString(wxArrayString &dest, const wxString &src, const wxString &delim // // Note: wxWidgets 2.9 / 3.0 has a wxJoin function, but we're using 2.8 so I had to make // my own. -wxString JoinString(const wxArrayString &src, const wxString &separator) +wxString JoinString(const wxArrayString& src, const wxString& separator) { - wxString dest; - for (int i = 0, len = src.GetCount(); i < len; ++i) { - if (src[i].IsEmpty()) - continue; - if (!dest.IsEmpty()) - dest += separator; - dest += src[i]; - } - return dest; + wxString dest; + for (int i = 0, len = src.GetCount(); i < len; ++i) + { + if (src[i].IsEmpty()) + continue; + if (!dest.IsEmpty()) + dest += separator; + dest += src[i]; + } + return dest; } -wxString JoinString(const wxChar **src, const wxString &separator) +wxString JoinString(const wxChar** src, const wxString& separator) { - wxString dest; - while (*src != NULL) { - if (*src[0] == 0) - continue; + wxString dest; + while (*src != NULL) + { + if (*src[0] == 0) + continue; - if (!dest.IsEmpty()) - dest += separator; - dest += *src; - ++src; - } - return dest; + if (!dest.IsEmpty()) + dest += separator; + dest += *src; + ++src; + } + return dest; } @@ -127,12 +129,12 @@ wxString JoinString(const wxChar **src, const wxString &separator) // This, so far, include types such as wxPoint, wxRect, and wxSize. // template -T Parse(const wxString &src, const wxString &separators = L",") +T Parse(const wxString& src, const wxString& separators = L",") { - T retval; - if (!TryParse(retval, src, separators)) - throw Exception::ParseError("Parse failure on call to " + fromUTF8(__WXFUNCTION__) + ": " + src); - return retval; + T retval; + if (!TryParse(retval, src, separators)) + throw Exception::ParseError("Parse failure on call to " + fromUTF8(__WXFUNCTION__) + ": " + src); + return retval; } @@ -141,104 +143,104 @@ T Parse(const wxString &src, const wxString &separators = L",") // -------------------------------------------------------------------------------------- // Converts a wxPoint into a comma-delimited string! -wxString ToString(const wxPoint &src, const wxString &separator) +wxString ToString(const wxPoint& src, const wxString& separator) { - return wxString() << src.x << separator << src.y; + return wxString() << src.x << separator << src.y; } -wxString ToString(const wxSize &src, const wxString &separator) +wxString ToString(const wxSize& src, const wxString& separator) { - return wxString() << src.GetWidth() << separator << src.GetHeight(); + return wxString() << src.GetWidth() << separator << src.GetHeight(); } // Converts a wxRect into a comma-delimited string! // Example: 32,64,128,5 -wxString ToString(const wxRect &src, const wxString &separator) +wxString ToString(const wxRect& src, const wxString& separator) { - return ToString(src.GetLeftTop(), separator) << separator << ToString(src.GetSize(), separator); + return ToString(src.GetLeftTop(), separator) << separator << ToString(src.GetSize(), separator); } // -------------------------------------------------------------------------------------- // Parse helpers for wxString! // -------------------------------------------------------------------------------------- -bool TryParse(wxPoint &dest, wxStringTokenizer &parts) +bool TryParse(wxPoint& dest, wxStringTokenizer& parts) { - long result[2]; + long result[2]; - if (!parts.HasMoreTokens() || !parts.GetNextToken().ToLong(&result[0])) - return false; - if (!parts.HasMoreTokens() || !parts.GetNextToken().ToLong(&result[1])) - return false; - dest.x = result[0]; - dest.y = result[1]; + if (!parts.HasMoreTokens() || !parts.GetNextToken().ToLong(&result[0])) + return false; + if (!parts.HasMoreTokens() || !parts.GetNextToken().ToLong(&result[1])) + return false; + dest.x = result[0]; + dest.y = result[1]; - return true; + return true; } -bool TryParse(wxSize &dest, wxStringTokenizer &parts) +bool TryParse(wxSize& dest, wxStringTokenizer& parts) { - long result[2]; + long result[2]; - if (!parts.HasMoreTokens() || !parts.GetNextToken().ToLong(&result[0])) - return false; - if (!parts.HasMoreTokens() || !parts.GetNextToken().ToLong(&result[1])) - return false; - dest.SetWidth(result[0]); - dest.SetHeight(result[1]); + if (!parts.HasMoreTokens() || !parts.GetNextToken().ToLong(&result[0])) + return false; + if (!parts.HasMoreTokens() || !parts.GetNextToken().ToLong(&result[1])) + return false; + dest.SetWidth(result[0]); + dest.SetHeight(result[1]); - return true; + return true; } // Tries to parse the given string into a wxPoint value at 'dest.' If the parse fails, the // method aborts and returns false. -bool TryParse(wxPoint &dest, const wxString &src, const wxPoint &defval, const wxString &separators) +bool TryParse(wxPoint& dest, const wxString& src, const wxPoint& defval, const wxString& separators) { - dest = defval; - wxStringTokenizer parts(src, separators); - return TryParse(dest, parts); + dest = defval; + wxStringTokenizer parts(src, separators); + return TryParse(dest, parts); } -bool TryParse(wxSize &dest, const wxString &src, const wxSize &defval, const wxString &separators) +bool TryParse(wxSize& dest, const wxString& src, const wxSize& defval, const wxString& separators) { - dest = defval; - wxStringTokenizer parts(src, separators); - return TryParse(dest, parts); + dest = defval; + wxStringTokenizer parts(src, separators); + return TryParse(dest, parts); } -bool TryParse(wxRect &dest, const wxString &src, const wxRect &defval, const wxString &separators) +bool TryParse(wxRect& dest, const wxString& src, const wxRect& defval, const wxString& separators) { - dest = defval; + dest = defval; - wxStringTokenizer parts(src, separators); + wxStringTokenizer parts(src, separators); - wxPoint point; - wxSize size; + wxPoint point; + wxSize size; - if (!TryParse(point, parts)) - return false; - if (!TryParse(size, parts)) - return false; + if (!TryParse(point, parts)) + return false; + if (!TryParse(size, parts)) + return false; - dest = wxRect(point, size); - return true; + dest = wxRect(point, size); + return true; } // returns TRUE if the parse is valid, or FALSE if it's a comment. -bool pxParseAssignmentString(const wxString &src, wxString &ldest, wxString &rdest) +bool pxParseAssignmentString(const wxString& src, wxString& ldest, wxString& rdest) { - if (src.StartsWith(L"--") || src.StartsWith(L"//") || src.StartsWith(L";")) - return false; + if (src.StartsWith(L"--") || src.StartsWith(L"//") || src.StartsWith(L";")) + return false; - ldest = src.BeforeFirst(L'=').Trim(true).Trim(false); - rdest = src.AfterFirst(L'=').Trim(true).Trim(false); + ldest = src.BeforeFirst(L'=').Trim(true).Trim(false); + rdest = src.AfterFirst(L'=').Trim(true).Trim(false); - return true; + return true; } -ParsedAssignmentString::ParsedAssignmentString(const wxString &src) +ParsedAssignmentString::ParsedAssignmentString(const wxString& src) { - IsComment = pxParseAssignmentString(src, lvalue, rvalue); + IsComment = pxParseAssignmentString(src, lvalue, rvalue); } // Performs a cross-platform puts operation, which adds CRs to naked LFs on Win32 platforms, @@ -249,37 +251,41 @@ ParsedAssignmentString::ParsedAssignmentString(const wxString &src) // from incoming data. Mac platforms may need an implementation of their own that converts // newlines to CRs...? // -void px_fputs(FILE *fp, const char *src) +void px_fputs(FILE* fp, const char* src) { - if (fp == NULL) - return; + if (fp == NULL) + return; #ifdef _WIN32 - // Windows needs CR's partnered with all newlines, or else notepad.exe can't view - // the stupid logfile. Best way is to write one char at a time.. >_< + // Windows needs CR's partnered with all newlines, or else notepad.exe can't view + // the stupid logfile. Best way is to write one char at a time.. >_< - const char *curchar = src; - bool prevcr = false; - while (*curchar != 0) { - if (*curchar == '\r') { - prevcr = true; - } else { - // Only write a CR/LF pair if the current LF is not prefixed nor - // post-fixed by a CR. - if (*curchar == '\n' && !prevcr && (*(curchar + 1) != '\r')) - fputs("\r\n", fp); - else - fputc(*curchar, fp); + const char* curchar = src; + bool prevcr = false; + while (*curchar != 0) + { + if (*curchar == '\r') + { + prevcr = true; + } + else + { + // Only write a CR/LF pair if the current LF is not prefixed nor + // post-fixed by a CR. + if (*curchar == '\n' && !prevcr && (*(curchar + 1) != '\r')) + fputs("\r\n", fp); + else + fputc(*curchar, fp); - prevcr = false; - } - ++curchar; - } + prevcr = false; + } + ++curchar; + } #else - // Linux is happy with plain old LFs. Not sure about Macs... does OSX still - // go by the old school Mac style of using Crs only? + // Linux is happy with plain old LFs. Not sure about Macs... does OSX still + // go by the old school Mac style of using Crs only? - fputs(src, fp); // fputs does not do automatic newlines, so it's ok! + fputs(src, fp); // fputs does not do automatic newlines, so it's ok! #endif } diff --git a/common/StringHelpers.h b/common/StringHelpers.h index 6efee1c7fb..2dccfacbb5 100644 --- a/common/StringHelpers.h +++ b/common/StringHelpers.h @@ -24,7 +24,7 @@ #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(str.c_str())) +#define WX_STR(str) (static_cast(str.c_str())) #endif // -------------------------------------------------------------------------------------- @@ -33,59 +33,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; - } + void Convert(const wxString& src) + { + m_result = src.ToUTF8(); + m_length = -1; + } - const char *data() const { return m_result; } + const char* data() const { return m_result; } - operator const char *() const - { - return m_result.data(); - } + 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 @@ -103,11 +103,11 @@ extern bool TryParse(wxRect &dest, const wxString &src, const wxRect &defval = w // struct ParsedAssignmentString { - wxString lvalue; - wxString rvalue; - bool IsComment; + wxString lvalue; + wxString rvalue; + bool IsComment; - ParsedAssignmentString(const wxString &src); + ParsedAssignmentString(const wxString& src); }; // ====================================================================================== @@ -139,40 +139,40 @@ typedef ScopedAlignedAlloc CharBufferType; class FastFormatAscii { protected: - CharBufferType m_dest; + CharBufferType m_dest; public: - FastFormatAscii(); - ~FastFormatAscii() = default; - FastFormatAscii &Write(const char *fmt, ...); - FastFormatAscii &WriteV(const char *fmt, va_list argptr); + FastFormatAscii(); + ~FastFormatAscii() = default; + 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; + } }; // -------------------------------------------------------------------------------------- @@ -181,54 +181,54 @@ public: class FastFormatUnicode { protected: - CharBufferType m_dest; - uint m_Length; + CharBufferType m_dest; + uint m_Length; public: - FastFormatUnicode(); - ~FastFormatUnicode() = default; + FastFormatUnicode(); + ~FastFormatUnicode() = default; - 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 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); diff --git a/common/ThreadTools.cpp b/common/ThreadTools.cpp index 5687645a05..daf09b0f07 100644 --- a/common/ThreadTools.cpp +++ b/common/ThreadTools.cpp @@ -33,12 +33,12 @@ const wxTimeSpan Threading::def_yieldgui_interval(0, 0, 0, 100); ConsoleLogSource_Threading::ConsoleLogSource_Threading() { - static const TraceLogDescriptor myDesc = - { - L"p&xThread", L"pxThread", - pxLt("Threading activity: start, detach, sync, deletion, etc.")}; + static const TraceLogDescriptor myDesc = + { + L"p&xThread", L"pxThread", + pxLt("Threading activity: start, detach, sync, deletion, etc.")}; - m_Descriptor = &myDesc; + m_Descriptor = &myDesc; } ConsoleLogSource_Threading pxConLog_Thread; @@ -47,18 +47,18 @@ ConsoleLogSource_Threading pxConLog_Thread; class StaticMutex : public Mutex { protected: - bool &m_DeletedFlag; + bool& m_DeletedFlag; public: - StaticMutex(bool &deletedFlag) - : m_DeletedFlag(deletedFlag) - { - } + StaticMutex(bool& deletedFlag) + : m_DeletedFlag(deletedFlag) + { + } - virtual ~StaticMutex() - { - m_DeletedFlag = true; - } + virtual ~StaticMutex() + { + m_DeletedFlag = true; + } }; static pthread_key_t curthread_key = 0; @@ -67,111 +67,115 @@ static s32 total_key_count = 0; static bool tkl_destructed = false; static StaticMutex total_key_lock(tkl_destructed); -static void make_curthread_key(const pxThread *thr) +static void make_curthread_key(const pxThread* thr) { - pxAssumeDev(!tkl_destructed, "total_key_lock is destroyed; program is shutting down; cannot create new thread key."); + pxAssumeDev(!tkl_destructed, "total_key_lock is destroyed; program is shutting down; cannot create new thread key."); - ScopedLock lock(total_key_lock); - if (total_key_count++ != 0) - return; + ScopedLock lock(total_key_lock); + if (total_key_count++ != 0) + return; - if (0 != pthread_key_create(&curthread_key, NULL)) { - pxThreadLog.Error(thr->GetName(), L"Thread key creation failed (probably out of memory >_<)"); - curthread_key = 0; - } + if (0 != pthread_key_create(&curthread_key, NULL)) + { + pxThreadLog.Error(thr->GetName(), L"Thread key creation failed (probably out of memory >_<)"); + curthread_key = 0; + } } static void unmake_curthread_key() { - ScopedLock lock; - if (!tkl_destructed) - lock.AssignAndLock(total_key_lock); + ScopedLock lock; + if (!tkl_destructed) + lock.AssignAndLock(total_key_lock); - if (--total_key_count > 0) - return; + if (--total_key_count > 0) + return; - if (curthread_key) - pthread_key_delete(curthread_key); + if (curthread_key) + pthread_key_delete(curthread_key); - curthread_key = 0; + curthread_key = 0; } void Threading::pxTestCancel() { - pthread_testcancel(); + pthread_testcancel(); } // Returns a handle to the current persistent thread. If the current thread does not belong // to the pxThread table, NULL is returned. Since the main/ui thread is not created // through pxThread it will also return NULL. Callers can use wxThread::IsMain() to // test if the NULL thread is the main thread. -pxThread *Threading::pxGetCurrentThread() +pxThread* Threading::pxGetCurrentThread() { - return !curthread_key ? NULL : (pxThread *)pthread_getspecific(curthread_key); + return !curthread_key ? NULL : (pxThread*)pthread_getspecific(curthread_key); } // returns the name of the current thread, or "Unknown" if the thread is neither a pxThread // nor the Main/UI thread. wxString Threading::pxGetCurrentThreadName() { - if (pxThread *thr = pxGetCurrentThread()) { - return thr->GetName(); - } else if (wxThread::IsMain()) { - return L"Main/UI"; - } + if (pxThread* thr = pxGetCurrentThread()) + { + return thr->GetName(); + } + else if (wxThread::IsMain()) + { + return L"Main/UI"; + } - return L"Unknown"; + return L"Unknown"; } void Threading::pxYield(int ms) { - if (pxThread *thr = pxGetCurrentThread()) - thr->Yield(ms); - else - Sleep(ms); + if (pxThread* thr = pxGetCurrentThread()) + thr->Yield(ms); + else + Sleep(ms); } // (intended for internal use only) // Returns true if the Wait is recursive, or false if the Wait is safe and should be // handled via normal yielding methods. -bool Threading::_WaitGui_RecursionGuard(const wxChar *name) +bool Threading::_WaitGui_RecursionGuard(const wxChar* name) { - AffinityAssert_AllowFrom_MainUI(); + AffinityAssert_AllowFrom_MainUI(); - // In order to avoid deadlock we need to make sure we cut some time to handle messages. - // But this can result in recursive yield calls, which would crash the app. Protect - // against them here and, if recursion is detected, perform a standard blocking wait. + // In order to avoid deadlock we need to make sure we cut some time to handle messages. + // But this can result in recursive yield calls, which would crash the app. Protect + // against them here and, if recursion is detected, perform a standard blocking wait. - static int __Guard = 0; - RecursionGuard guard(__Guard); + static int __Guard = 0; + RecursionGuard guard(__Guard); - //if( pxAssertDev( !guard.IsReentrant(), "Recursion during UI-bound threading wait object." ) ) return false; + //if( pxAssertDev( !guard.IsReentrant(), "Recursion during UI-bound threading wait object." ) ) return false; - if (!guard.IsReentrant()) - return false; - pxThreadLog.Write(pxGetCurrentThreadName(), - pxsFmt(L"Yield recursion in %s; opening modal dialog.", name)); - return true; + if (!guard.IsReentrant()) + return false; + pxThreadLog.Write(pxGetCurrentThreadName(), + pxsFmt(L"Yield recursion in %s; opening modal dialog.", name)); + return true; } __fi void Threading::Timeslice() { - sched_yield(); + sched_yield(); } -void Threading::pxThread::_pt_callback_cleanup(void *handle) +void Threading::pxThread::_pt_callback_cleanup(void* handle) { - ((pxThread *)handle)->_ThreadCleanup(); + ((pxThread*)handle)->_ThreadCleanup(); } -Threading::pxThread::pxThread(const wxString &name) - : m_name(name) - , m_thread() - , m_native_id(0) - , m_native_handle(0) - , m_detached(true) // start out with m_thread in detached/invalid state - , m_running(false) +Threading::pxThread::pxThread(const wxString& name) + : m_name(name) + , m_thread() + , m_native_id(0) + , m_native_handle(0) + , m_detached(true) // start out with m_thread in detached/invalid state + , m_running(false) { } @@ -184,50 +188,53 @@ Threading::pxThread::pxThread(const wxString &name) // like marrying your sister, and then cheating on her with your daughter. Threading::pxThread::~pxThread() { - try { - pxThreadLog.Write(GetName(), L"Executing default destructor!"); + try + { + pxThreadLog.Write(GetName(), L"Executing default destructor!"); - if (m_running) { - pxThreadLog.Write(GetName(), L"Waiting for running thread to end..."); - m_mtx_InThread.Wait(); - pxThreadLog.Write(GetName(), L"Thread ended gracefully."); - } - Threading::Sleep(1); - Detach(); - } - DESTRUCTOR_CATCHALL + if (m_running) + { + pxThreadLog.Write(GetName(), L"Waiting for running thread to end..."); + m_mtx_InThread.Wait(); + pxThreadLog.Write(GetName(), L"Thread ended gracefully."); + } + Threading::Sleep(1); + Detach(); + } + DESTRUCTOR_CATCHALL } -bool Threading::pxThread::AffinityAssert_AllowFromSelf(const DiagnosticOrigin &origin) const +bool Threading::pxThread::AffinityAssert_AllowFromSelf(const DiagnosticOrigin& origin) const { - if (IsSelf()) - return true; + if (IsSelf()) + return true; - if (IsDevBuild) - pxOnAssert(origin, pxsFmt(L"Thread affinity violation: Call allowed from '%s' thread only.", WX_STR(GetName()))); + if (IsDevBuild) + pxOnAssert(origin, pxsFmt(L"Thread affinity violation: Call allowed from '%s' thread only.", WX_STR(GetName()))); - return false; + return false; } -bool Threading::pxThread::AffinityAssert_DisallowFromSelf(const DiagnosticOrigin &origin) const +bool Threading::pxThread::AffinityAssert_DisallowFromSelf(const DiagnosticOrigin& origin) const { - if (!IsSelf()) - return true; + if (!IsSelf()) + return true; - if (IsDevBuild) - pxOnAssert(origin, pxsFmt(L"Thread affinity violation: Call is *not* allowed from '%s' thread.", WX_STR(GetName()))); + if (IsDevBuild) + pxOnAssert(origin, pxsFmt(L"Thread affinity violation: Call is *not* allowed from '%s' thread.", WX_STR(GetName()))); - return false; + return false; } -void Threading::pxThread::FrankenMutex(Mutex &mutex) +void Threading::pxThread::FrankenMutex(Mutex& mutex) { - if (mutex.RecreateIfLocked()) { - // Our lock is bupkis, which means the previous thread probably deadlocked. - // Let's create a new mutex lock to replace it. + if (mutex.RecreateIfLocked()) + { + // Our lock is bupkis, which means the previous thread probably deadlocked. + // Let's create a new mutex lock to replace it. - pxThreadLog.Error(GetName(), L"Possible deadlock detected on restarted mutex!"); - } + pxThreadLog.Error(GetName(), L"Possible deadlock detected on restarted mutex!"); + } } // Main entry point for starting or e-starting a persistent thread. This function performs necessary @@ -238,53 +245,56 @@ void Threading::pxThread::FrankenMutex(Mutex &mutex) // This function should not be called from the owner thread. void Threading::pxThread::Start() { - // Prevents sudden parallel startup, and or parallel startup + cancel: - ScopedLock startlock(m_mtx_start); - if (m_running) { - pxThreadLog.Write(GetName(), L"Start() called on running thread; ignorning..."); - return; - } + // Prevents sudden parallel startup, and or parallel startup + cancel: + ScopedLock startlock(m_mtx_start); + if (m_running) + { + pxThreadLog.Write(GetName(), L"Start() called on running thread; ignorning..."); + return; + } - Detach(); // clean up previous thread handle, if one exists. - OnStart(); + Detach(); // clean up previous thread handle, if one exists. + OnStart(); - m_except = NULL; + m_except = NULL; - pxThreadLog.Write(GetName(), L"Calling pthread_create..."); - if (pthread_create(&m_thread, NULL, _internal_callback, this) != 0) - throw Exception::ThreadCreationError(this).SetDiagMsg(L"Thread creation error: " + wxString(std::strerror(errno))); + pxThreadLog.Write(GetName(), L"Calling pthread_create..."); + if (pthread_create(&m_thread, NULL, _internal_callback, this) != 0) + throw Exception::ThreadCreationError(this).SetDiagMsg(L"Thread creation error: " + wxString(std::strerror(errno))); #ifdef ASAN_WORKAROUND - // Recent Asan + libc6 do pretty bad stuff on the thread init => https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77982 - // - // In our case, the semaphore was posted (counter is 1) but thread is still - // waiting... So waits 100ms and checks the counter value manually - if (!m_sem_startup.WaitWithoutYield(wxTimeSpan(0, 0, 0, 100))) { - if (m_sem_startup.Count() == 0) - throw Exception::ThreadCreationError(this).SetDiagMsg(L"Thread creation error: %s thread never posted startup semaphore."); - } + // Recent Asan + libc6 do pretty bad stuff on the thread init => https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77982 + // + // In our case, the semaphore was posted (counter is 1) but thread is still + // waiting... So waits 100ms and checks the counter value manually + if (!m_sem_startup.WaitWithoutYield(wxTimeSpan(0, 0, 0, 100))) + { + if (m_sem_startup.Count() == 0) + throw Exception::ThreadCreationError(this).SetDiagMsg(L"Thread creation error: %s thread never posted startup semaphore."); + } #else - if (!m_sem_startup.WaitWithoutYield(wxTimeSpan(0, 0, 3, 0))) { - RethrowException(); + if (!m_sem_startup.WaitWithoutYield(wxTimeSpan(0, 0, 3, 0))) + { + RethrowException(); - // And if the thread threw nothing of its own: - throw Exception::ThreadCreationError(this).SetDiagMsg(L"Thread creation error: %s thread never posted startup semaphore."); - } + // And if the thread threw nothing of its own: + throw Exception::ThreadCreationError(this).SetDiagMsg(L"Thread creation error: %s thread never posted startup semaphore."); + } #endif - // Event Rationale (above): Performing this semaphore wait on the created thread is "slow" in the - // sense that it stalls the calling thread completely until the new thread is created - // (which may not always be desirable). But too bad. In order to safely use 'running' locks - // and detachment management, this *has* to be done. By rule, starting new threads shouldn't - // be done very often anyway, hence the concept of Threadpooling for rapidly rotating tasks. - // (and indeed, this semaphore wait might, in fact, be very swift compared to other kernel - // overhead in starting threads). + // Event Rationale (above): Performing this semaphore wait on the created thread is "slow" in the + // sense that it stalls the calling thread completely until the new thread is created + // (which may not always be desirable). But too bad. In order to safely use 'running' locks + // and detachment management, this *has* to be done. By rule, starting new threads shouldn't + // be done very often anyway, hence the concept of Threadpooling for rapidly rotating tasks. + // (and indeed, this semaphore wait might, in fact, be very swift compared to other kernel + // overhead in starting threads). - // (this could also be done using operating system specific calls, since any threaded OS has - // functions that allow us to see if a thread is running or not, and to block against it even if - // it's been detached -- removing the need for m_mtx_InThread and the semaphore wait above. But - // pthreads kinda lacks that stuff, since pthread_join() has no timeout option making it im- - // possible to safely block against a running thread) + // (this could also be done using operating system specific calls, since any threaded OS has + // functions that allow us to see if a thread is running or not, and to block against it even if + // it's been detached -- removing the need for m_mtx_InThread and the semaphore wait above. But + // pthreads kinda lacks that stuff, since pthread_join() has no timeout option making it im- + // possible to safely block against a running thread) } // Returns: TRUE if the detachment was performed, or FALSE if the thread was @@ -292,26 +302,27 @@ void Threading::pxThread::Start() // This function should not be called from the owner thread. bool Threading::pxThread::Detach() { - AffinityAssert_DisallowFromSelf(pxDiagSpot); + AffinityAssert_DisallowFromSelf(pxDiagSpot); - if (m_detached.exchange(true)) - return false; - pthread_detach(m_thread); - return true; + if (m_detached.exchange(true)) + return false; + pthread_detach(m_thread); + return true; } bool Threading::pxThread::_basecancel() { - if (!m_running) - return false; + if (!m_running) + return false; - if (m_detached) { - pxThreadLog.Warn(GetName(), L"Ignoring attempted cancellation of detached thread."); - return false; - } + if (m_detached) + { + pxThreadLog.Warn(GetName(), L"Ignoring attempted cancellation of detached thread."); + return false; + } - pthread_cancel(m_thread); - return true; + pthread_cancel(m_thread); + return true; } // Remarks: @@ -330,34 +341,35 @@ bool Threading::pxThread::_basecancel() // void Threading::pxThread::Cancel(bool isBlocking) { - AffinityAssert_DisallowFromSelf(pxDiagSpot); + AffinityAssert_DisallowFromSelf(pxDiagSpot); - // Prevent simultaneous startup and cancel, necessary to avoid - ScopedLock startlock(m_mtx_start); + // Prevent simultaneous startup and cancel, necessary to avoid + ScopedLock startlock(m_mtx_start); - if (!_basecancel()) - return; + if (!_basecancel()) + return; - if (isBlocking) { - WaitOnSelf(m_mtx_InThread); - Detach(); - } + if (isBlocking) + { + WaitOnSelf(m_mtx_InThread); + Detach(); + } } -bool Threading::pxThread::Cancel(const wxTimeSpan ×pan) +bool Threading::pxThread::Cancel(const wxTimeSpan& timespan) { - AffinityAssert_DisallowFromSelf(pxDiagSpot); + AffinityAssert_DisallowFromSelf(pxDiagSpot); - // Prevent simultaneous startup and cancel: - ScopedLock startlock(m_mtx_start); + // Prevent simultaneous startup and cancel: + ScopedLock startlock(m_mtx_start); - if (!_basecancel()) - return true; + if (!_basecancel()) + return true; - if (!WaitOnSelf(m_mtx_InThread, timespan)) - return false; - Detach(); - return true; + if (!WaitOnSelf(m_mtx_InThread, timespan)) + return false; + Detach(); + return true; } @@ -373,32 +385,32 @@ bool Threading::pxThread::Cancel(const wxTimeSpan ×pan) // void Threading::pxThread::Block() { - AffinityAssert_DisallowFromSelf(pxDiagSpot); - WaitOnSelf(m_mtx_InThread); + AffinityAssert_DisallowFromSelf(pxDiagSpot); + WaitOnSelf(m_mtx_InThread); } -bool Threading::pxThread::Block(const wxTimeSpan &timeout) +bool Threading::pxThread::Block(const wxTimeSpan& timeout) { - AffinityAssert_DisallowFromSelf(pxDiagSpot); - return WaitOnSelf(m_mtx_InThread, timeout); + AffinityAssert_DisallowFromSelf(pxDiagSpot); + return WaitOnSelf(m_mtx_InThread, timeout); } bool Threading::pxThread::IsSelf() const { - // Detached threads may have their pthread handles recycled as newer threads, causing - // false IsSelf reports. - return !m_detached && (pthread_self() == m_thread); + // Detached threads may have their pthread handles recycled as newer threads, causing + // false IsSelf reports. + return !m_detached && (pthread_self() == m_thread); } bool Threading::pxThread::IsRunning() const { - return m_running; + return m_running; } -void Threading::pxThread::AddListener(EventListener_Thread &evt) +void Threading::pxThread::AddListener(EventListener_Thread& evt) { - evt.SetThread(this); - m_evtsrc_OnDelete.Add(evt); + evt.SetThread(this); + m_evtsrc_OnDelete.Add(evt); } // Throws an exception if the thread encountered one. Uses the BaseException's Rethrow() method, @@ -406,49 +418,51 @@ void Threading::pxThread::AddListener(EventListener_Thread &evt) // the thread will have allowed itself to terminate properly. void Threading::pxThread::RethrowException() const { - // Thread safety note: always detach the m_except pointer. If we checked it for NULL, the - // pointer might still be invalid after detachment, so might as well just detach and check - // after. + // Thread safety note: always detach the m_except pointer. If we checked it for NULL, the + // pointer might still be invalid after detachment, so might as well just detach and check + // after. - ScopedExcept ptr(const_cast(this)->m_except.DetachPtr()); - if (ptr) - ptr->Rethrow(); + ScopedExcept ptr(const_cast(this)->m_except.DetachPtr()); + if (ptr) + ptr->Rethrow(); } static bool m_BlockDeletions = false; bool Threading::AllowDeletions() { - AffinityAssert_AllowFrom_MainUI(); - return !m_BlockDeletions; + AffinityAssert_AllowFrom_MainUI(); + return !m_BlockDeletions; } void Threading::YieldToMain() { - m_BlockDeletions = true; - wxTheApp->Yield(true); - m_BlockDeletions = false; + m_BlockDeletions = true; + wxTheApp->Yield(true); + m_BlockDeletions = false; } -void Threading::pxThread::_selfRunningTest(const wxChar *name) const +void Threading::pxThread::_selfRunningTest(const wxChar* name) const { - if (HasPendingException()) { - pxThreadLog.Error(GetName(), pxsFmt(L"An exception was thrown while waiting on a %s.", name)); - RethrowException(); - } + if (HasPendingException()) + { + pxThreadLog.Error(GetName(), pxsFmt(L"An exception was thrown while waiting on a %s.", name)); + RethrowException(); + } - if (!m_running) { - throw Exception::CancelEvent(pxsFmt( - L"Blocking thread %s was terminated while another thread was waiting on a %s.", - WX_STR(GetName()), name)); - } + if (!m_running) + { + throw Exception::CancelEvent(pxsFmt( + L"Blocking thread %s was terminated while another thread was waiting on a %s.", + WX_STR(GetName()), name)); + } - // Thread is still alive and kicking (for now) -- yield to other messages and hope - // that impending chaos does not ensue. [it shouldn't since we block pxThread - // objects from being deleted until outside the scope of a mutex/semaphore wait). + // Thread is still alive and kicking (for now) -- yield to other messages and hope + // that impending chaos does not ensue. [it shouldn't since we block pxThread + // objects from being deleted until outside the scope of a mutex/semaphore wait). - if ((wxTheApp != NULL) && wxThread::IsMain() && !_WaitGui_RecursionGuard(L"WaitForSelf")) - Threading::YieldToMain(); + if ((wxTheApp != NULL) && wxThread::IsMain() && !_WaitGui_RecursionGuard(L"WaitForSelf")) + Threading::YieldToMain(); } // This helper function is a deadlock-safe method of waiting on a semaphore in a pxThread. If the @@ -462,16 +476,17 @@ void Threading::pxThread::_selfRunningTest(const wxChar *name) const // This function will rethrow exceptions raised by the persistent thread, if it throws an error // while the calling thread is blocking (which also means the persistent thread has terminated). // -void Threading::pxThread::WaitOnSelf(Semaphore &sem) const +void Threading::pxThread::WaitOnSelf(Semaphore& sem) const { - if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) - return; + if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) + return; - while (true) { - if (sem.WaitWithoutYield(wxTimeSpan(0, 0, 0, 333))) - return; - _selfRunningTest(L"semaphore"); - } + while (true) + { + if (sem.WaitWithoutYield(wxTimeSpan(0, 0, 0, 333))) + return; + _selfRunningTest(L"semaphore"); + } } // This helper function is a deadlock-safe method of waiting on a mutex in a pxThread. @@ -487,52 +502,55 @@ void Threading::pxThread::WaitOnSelf(Semaphore &sem) const // error while the calling thread is blocking (which also means the persistent thread has // terminated). // -void Threading::pxThread::WaitOnSelf(Mutex &mutex) const +void Threading::pxThread::WaitOnSelf(Mutex& mutex) const { - if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) - return; + if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) + return; - while (true) { - if (mutex.WaitWithoutYield(wxTimeSpan(0, 0, 0, 333))) - return; - _selfRunningTest(L"mutex"); - } + while (true) + { + if (mutex.WaitWithoutYield(wxTimeSpan(0, 0, 0, 333))) + return; + _selfRunningTest(L"mutex"); + } } static const wxTimeSpan SelfWaitInterval(0, 0, 0, 333); -bool Threading::pxThread::WaitOnSelf(Semaphore &sem, const wxTimeSpan &timeout) const +bool Threading::pxThread::WaitOnSelf(Semaphore& sem, const wxTimeSpan& timeout) const { - if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) - return true; + if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) + return true; - wxTimeSpan runningout(timeout); + wxTimeSpan runningout(timeout); - while (runningout.GetMilliseconds() > 0) { - const wxTimeSpan interval((SelfWaitInterval < runningout) ? SelfWaitInterval : runningout); - if (sem.WaitWithoutYield(interval)) - return true; - _selfRunningTest(L"semaphore"); - runningout -= interval; - } - return false; + while (runningout.GetMilliseconds() > 0) + { + const wxTimeSpan interval((SelfWaitInterval < runningout) ? SelfWaitInterval : runningout); + if (sem.WaitWithoutYield(interval)) + return true; + _selfRunningTest(L"semaphore"); + runningout -= interval; + } + return false; } -bool Threading::pxThread::WaitOnSelf(Mutex &mutex, const wxTimeSpan &timeout) const +bool Threading::pxThread::WaitOnSelf(Mutex& mutex, const wxTimeSpan& timeout) const { - if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) - return true; + if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) + return true; - wxTimeSpan runningout(timeout); + wxTimeSpan runningout(timeout); - while (runningout.GetMilliseconds() > 0) { - const wxTimeSpan interval((SelfWaitInterval < runningout) ? SelfWaitInterval : runningout); - if (mutex.WaitWithoutYield(interval)) - return true; - _selfRunningTest(L"mutex"); - runningout -= interval; - } - return false; + while (runningout.GetMilliseconds() > 0) + { + const wxTimeSpan interval((SelfWaitInterval < runningout) ? SelfWaitInterval : runningout); + if (mutex.WaitWithoutYield(interval)) + return true; + _selfRunningTest(L"mutex"); + runningout -= interval; + } + return false; } // Inserts a thread cancellation point. If the thread has received a cancel request, this @@ -541,36 +559,39 @@ bool Threading::pxThread::WaitOnSelf(Mutex &mutex, const wxTimeSpan &timeout) co // and cleanup, or use the DoThreadCleanup() override to perform resource cleanup). void Threading::pxThread::TestCancel() const { - AffinityAssert_AllowFromSelf(pxDiagSpot); - pthread_testcancel(); + AffinityAssert_AllowFromSelf(pxDiagSpot); + pthread_testcancel(); } // Executes the virtual member method void Threading::pxThread::_try_virtual_invoke(void (pxThread::*method)()) { - try { - (this->*method)(); - } + try + { + (this->*method)(); + } - // ---------------------------------------------------------------------------- - // Neat repackaging for STL Runtime errors... - // - catch (std::runtime_error &ex) { - m_except = new Exception::RuntimeError(ex, WX_STR(GetName())); - } + // ---------------------------------------------------------------------------- + // Neat repackaging for STL Runtime errors... + // + catch (std::runtime_error& ex) + { + m_except = new Exception::RuntimeError(ex, WX_STR(GetName())); + } - // ---------------------------------------------------------------------------- - catch (Exception::RuntimeError &ex) { - BaseException *woot = ex.Clone(); - woot->DiagMsg() += pxsFmt(L"(thread:%s)", WX_STR(GetName())); - m_except = woot; - } + // ---------------------------------------------------------------------------- + catch (Exception::RuntimeError& ex) + { + BaseException* woot = ex.Clone(); + woot->DiagMsg() += pxsFmt(L"(thread:%s)", WX_STR(GetName())); + m_except = woot; + } #ifndef PCSX2_DEVBUILD - // ---------------------------------------------------------------------------- - // Bleh... don't bother with std::exception. runtime_error should catch anything - // useful coming out of the core STL libraries anyway, and these are best handled by - // the MSVC debugger (or by silent random annoying fail on debug-less linux). - /*catch( std::logic_error& ex ) + // ---------------------------------------------------------------------------- + // Bleh... don't bother with std::exception. runtime_error should catch anything + // useful coming out of the core STL libraries anyway, and these are best handled by + // the MSVC debugger (or by silent random annoying fail on debug-less linux). + /*catch( std::logic_error& ex ) { throw BaseException( pxsFmt( L"STL Logic Error (thread:%s): %s", WX_STR(GetName()), WX_STR(fromUTF8( ex.what() )) ) @@ -582,14 +603,15 @@ void Threading::pxThread::_try_virtual_invoke(void (pxThread::*method)()) WX_STR(GetName()), WX_STR(fromUTF8( ex.what() )) ) ); }*/ - // ---------------------------------------------------------------------------- - // BaseException -- same deal as LogicErrors. - // - catch (BaseException &ex) { - BaseException *woot = ex.Clone(); - woot->DiagMsg() += pxsFmt(L"(thread:%s)", WX_STR(GetName())); - m_except = woot; - } + // ---------------------------------------------------------------------------- + // BaseException -- same deal as LogicErrors. + // + catch (BaseException& ex) + { + BaseException* woot = ex.Clone(); + woot->DiagMsg() += pxsFmt(L"(thread:%s)", WX_STR(GetName())); + m_except = woot; + } #endif } @@ -597,25 +619,25 @@ void Threading::pxThread::_try_virtual_invoke(void (pxThread::*method)()) // OnCleanupInThread() to extend cleanup functionality. void Threading::pxThread::_ThreadCleanup() { - AffinityAssert_AllowFromSelf(pxDiagSpot); - _try_virtual_invoke(&pxThread::OnCleanupInThread); - m_mtx_InThread.Release(); + AffinityAssert_AllowFromSelf(pxDiagSpot); + _try_virtual_invoke(&pxThread::OnCleanupInThread); + m_mtx_InThread.Release(); - // Must set m_running LAST, as thread destructors depend on this value (it is used - // to avoid destruction of the thread until all internal data use has stopped. - m_running = false; + // Must set m_running LAST, as thread destructors depend on this value (it is used + // to avoid destruction of the thread until all internal data use has stopped. + m_running = false; } wxString Threading::pxThread::GetName() const { - ScopedLock lock(m_mtx_ThreadName); - return m_name; + ScopedLock lock(m_mtx_ThreadName); + return m_name; } -void Threading::pxThread::SetName(const wxString &newname) +void Threading::pxThread::SetName(const wxString& newname) { - ScopedLock lock(m_mtx_ThreadName); - m_name = newname; + ScopedLock lock(m_mtx_ThreadName); + m_name = newname; } // This override is called by PeristentThread when the thread is first created, prior to @@ -627,82 +649,82 @@ void Threading::pxThread::SetName(const wxString &newname) // void Threading::pxThread::OnStartInThread() { - m_detached = false; - m_running = true; + m_detached = false; + m_running = true; - _platform_specific_OnStartInThread(); + _platform_specific_OnStartInThread(); } void Threading::pxThread::_internal_execute() { - m_mtx_InThread.Acquire(); + m_mtx_InThread.Acquire(); - _DoSetThreadName(GetName()); - make_curthread_key(this); - if (curthread_key) - pthread_setspecific(curthread_key, this); + _DoSetThreadName(GetName()); + make_curthread_key(this); + if (curthread_key) + pthread_setspecific(curthread_key, this); - OnStartInThread(); - m_sem_startup.Post(); + OnStartInThread(); + m_sem_startup.Post(); - _try_virtual_invoke(&pxThread::ExecuteTaskInThread); + _try_virtual_invoke(&pxThread::ExecuteTaskInThread); } // Called by Start, prior to actual starting of the thread, and after any previous // running thread has been canceled or detached. void Threading::pxThread::OnStart() { - m_native_handle = 0; - m_native_id = 0; + m_native_handle = 0; + m_native_id = 0; - FrankenMutex(m_mtx_InThread); - m_sem_event.Reset(); - m_sem_startup.Reset(); + FrankenMutex(m_mtx_InThread); + m_sem_event.Reset(); + m_sem_startup.Reset(); } // Extending classes that override this method should always call it last from their // personal implementations. void Threading::pxThread::OnCleanupInThread() { - if (curthread_key) - pthread_setspecific(curthread_key, NULL); + if (curthread_key) + pthread_setspecific(curthread_key, NULL); - unmake_curthread_key(); + unmake_curthread_key(); - _platform_specific_OnCleanupInThread(); + _platform_specific_OnCleanupInThread(); - m_native_handle = 0; - m_native_id = 0; + m_native_handle = 0; + m_native_id = 0; - m_evtsrc_OnDelete.Dispatch(0); + m_evtsrc_OnDelete.Dispatch(0); } // passed into pthread_create, and is used to dispatch the thread's object oriented // callback function -void *Threading::pxThread::_internal_callback(void *itsme) +void* Threading::pxThread::_internal_callback(void* itsme) { - if (!pxAssertDev(itsme != NULL, wxNullChar)) - return NULL; + if (!pxAssertDev(itsme != NULL, wxNullChar)) + return NULL; - internal_callback_helper(itsme); - return nullptr; + internal_callback_helper(itsme); + return nullptr; } // __try is used in pthread_cleanup_push when CLEANUP_SEH is used as the cleanup model. // That can't be used in a function that has objects that require unwinding (compile // error C2712), so move it into a separate function. -void Threading::pxThread::internal_callback_helper(void *itsme) +void Threading::pxThread::internal_callback_helper(void* itsme) { - pxThread &owner = *static_cast(itsme); + pxThread& owner = *static_cast(itsme); - pthread_cleanup_push(_pt_callback_cleanup, itsme); - owner._internal_execute(); - pthread_cleanup_pop(true); + pthread_cleanup_push(_pt_callback_cleanup, itsme); + owner._internal_execute(); + pthread_cleanup_pop(true); } -void Threading::pxThread::_DoSetThreadName(const wxString &name) +void Threading::pxThread::_DoSetThreadName(const wxString& name) { - _DoSetThreadName(static_cast(name.ToUTF8())); + _DoSetThreadName(static_cast(name.ToUTF8())); } // -------------------------------------------------------------------------------------- @@ -746,23 +768,23 @@ void Threading::WaitEvent::Wait() wxString Exception::BaseThreadError::FormatDiagnosticMessage() const { - wxString null_str(L"Null Thread Object"); - return pxsFmt(m_message_diag, (m_thread == NULL) ? WX_STR(null_str) : WX_STR(m_thread->GetName())); + wxString null_str(L"Null Thread Object"); + return pxsFmt(m_message_diag, (m_thread == NULL) ? WX_STR(null_str) : WX_STR(m_thread->GetName())); } wxString Exception::BaseThreadError::FormatDisplayMessage() const { - wxString null_str(L"Null Thread Object"); - return pxsFmt(m_message_user, (m_thread == NULL) ? WX_STR(null_str) : WX_STR(m_thread->GetName())); + wxString null_str(L"Null Thread Object"); + return pxsFmt(m_message_user, (m_thread == NULL) ? WX_STR(null_str) : WX_STR(m_thread->GetName())); } -pxThread &Exception::BaseThreadError::Thread() +pxThread& Exception::BaseThreadError::Thread() { - pxAssertDev(m_thread != NULL, "NULL thread object on ThreadError exception."); - return *m_thread; + pxAssertDev(m_thread != NULL, "NULL thread object on ThreadError exception."); + return *m_thread; } -const pxThread &Exception::BaseThreadError::Thread() const +const pxThread& Exception::BaseThreadError::Thread() const { - pxAssertDev(m_thread != NULL, "NULL thread object on ThreadError exception."); - return *m_thread; + pxAssertDev(m_thread != NULL, "NULL thread object on ThreadError exception."); + return *m_thread; } diff --git a/common/Threading.h b/common/Threading.h index 9a409af4bd..1f188bb8a2 100644 --- a/common/Threading.h +++ b/common/Threading.h @@ -32,7 +32,7 @@ #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 @@ -40,25 +40,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; @@ -88,97 +88,97 @@ 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 Threading 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."); + } + }; +} // namespace Exception namespace Threading { -// -------------------------------------------------------------------------------------- -// Platform Specific External APIs -// -------------------------------------------------------------------------------------- -// The following set of documented functions have Linux/Win32 specific implementations, -// which are found in WinThreads.cpp and LnxThreads.cpp + // -------------------------------------------------------------------------------------- + // Platform Specific External APIs + // -------------------------------------------------------------------------------------- + // 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) @@ -196,230 +196,230 @@ extern void Sleep(int ms); }; #endif -// -------------------------------------------------------------------------------------- -// NonblockingMutex -// -------------------------------------------------------------------------------------- -// This is a very simple non-blocking mutex, which behaves similarly to pthread_mutex's -// trylock(), but without any of the extra overhead needed to set up a structure capable -// of blocking waits. It basically optimizes to a single InterlockedExchange. -// -// Simple use: if TryAcquire() returns false, the Bool is already interlocked by another thread. -// If TryAcquire() returns true, you've locked the object and are *responsible* for unlocking -// it later. -// -class NonblockingMutex -{ -protected: - std::atomic_flag val; + // -------------------------------------------------------------------------------------- + // NonblockingMutex + // -------------------------------------------------------------------------------------- + // This is a very simple non-blocking mutex, which behaves similarly to pthread_mutex's + // trylock(), but without any of the extra overhead needed to set up a structure capable + // of blocking waits. It basically optimizes to a single InterlockedExchange. + // + // Simple use: if TryAcquire() returns false, the Bool is already interlocked by another thread. + // If TryAcquire() returns true, you've locked the object and are *responsible* for unlocking + // it later. + // + class NonblockingMutex + { + protected: + std::atomic_flag val; -public: - NonblockingMutex() { val.clear(); } - virtual ~NonblockingMutex() = default; + public: + NonblockingMutex() { val.clear(); } + virtual ~NonblockingMutex() = default; - bool TryAcquire() noexcept - { - return !val.test_and_set(); - } + bool TryAcquire() noexcept + { + 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(); + public: + Semaphore(); + virtual ~Semaphore(); - 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(); - virtual bool IsRecursive() const { return false; } + public: + Mutex(); + virtual ~Mutex(); + 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(); - virtual bool IsRecursive() const { return true; } -}; + class MutexRecursive : public Mutex + { + public: + MutexRecursive(); + virtual ~MutexRecursive(); + 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(); - explicit ScopedLock(const Mutex *locker = NULL); - explicit ScopedLock(const Mutex &locker); - void AssignAndLock(const Mutex &locker); - void AssignAndLock(const Mutex *locker); + public: + virtual ~ScopedLock(); + 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() = default; - bool Failed() const { return !m_IsLocked; } -}; + class ScopedTryLock : public ScopedLock + { + public: + ScopedTryLock(const Mutex& locker) + : ScopedLock(locker, true) + { + } + virtual ~ScopedTryLock() = default; + bool Failed() const { return !m_IsLocked; } + }; -// -------------------------------------------------------------------------------------- -// ScopedNonblockingLock -// -------------------------------------------------------------------------------------- -// A ScopedTryLock branded for use with Nonblocking mutexes. See ScopedTryLock for details. -// -class ScopedNonblockingLock -{ - DeclareNoncopyableObject(ScopedNonblockingLock); + // -------------------------------------------------------------------------------------- + // ScopedNonblockingLock + // -------------------------------------------------------------------------------------- + // A ScopedTryLock branded for use with Nonblocking mutexes. See ScopedTryLock for details. + // + 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() - { - if (m_IsLocked) - m_lock.Release(); - } + virtual ~ScopedNonblockingLock() + { + if (m_IsLocked) + m_lock.Release(); + } - bool Failed() const { return !m_IsLocked; } -}; + bool Failed() const { return !m_IsLocked; } + }; -// -------------------------------------------------------------------------------------- -// ScopedLockBool -// -------------------------------------------------------------------------------------- -// A ScopedLock in which you specify an external bool to get updated on locks/unlocks. -// Note that the isLockedBool should only be used as an indicator for the locked status, -// and not actually depended on for thread synchronization... + // -------------------------------------------------------------------------------------- + // ScopedLockBool + // -------------------------------------------------------------------------------------- + // A ScopedLock in which you specify an external bool to get updated on locks/unlocks. + // 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 &m_bool; + struct ScopedLockBool + { + ScopedLock m_lock; + std::atomic& m_bool; - ScopedLockBool(Mutex &mutexToLock, std::atomic &isLockedBool) - : m_lock(mutexToLock) - , m_bool(isLockedBool) - { - m_bool.store(m_lock.IsLocked(), std::memory_order_relaxed); - } - virtual ~ScopedLockBool() - { - 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& isLockedBool) + : m_lock(mutexToLock) + , m_bool(isLockedBool) + { + m_bool.store(m_lock.IsLocked(), std::memory_order_relaxed); + } + virtual ~ScopedLockBool() + { + 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(); + } + }; +} // namespace Threading diff --git a/common/ThreadingDialogs.cpp b/common/ThreadingDialogs.cpp index f63e3280ea..0723fafe01 100644 --- a/common/ThreadingDialogs.cpp +++ b/common/ThreadingDialogs.cpp @@ -25,60 +25,60 @@ wxDEFINE_EVENT(pxEvt_ThreadedTaskComplete, wxCommandEvent); // -------------------------------------------------------------------------------------- wxIMPLEMENT_DYNAMIC_CLASS(WaitForTaskDialog, wxDialogWithHelpers); -Threading::WaitForTaskDialog::WaitForTaskDialog(const wxString &title, const wxString &heading) - : wxDialogWithHelpers(NULL, _("Waiting for tasks...")) +Threading::WaitForTaskDialog::WaitForTaskDialog(const wxString& title, const wxString& heading) + : wxDialogWithHelpers(NULL, _("Waiting for tasks...")) //, m_Timer(this) { - SetMinWidth(300); + SetMinWidth(300); - //m_sem = sem; - //m_mutex = mutex; + //m_sem = sem; + //m_mutex = mutex; - wxString m_title(title); - wxString m_heading(heading); + wxString m_title(title); + wxString m_heading(heading); - if (m_title.IsEmpty()) - m_title = _("Waiting for task..."); - if (m_heading.IsEmpty()) - m_heading = m_title; + if (m_title.IsEmpty()) + m_title = _("Waiting for task..."); + if (m_heading.IsEmpty()) + m_heading = m_title; - Bind(pxEvt_ThreadedTaskComplete, &WaitForTaskDialog::OnTaskComplete, this); + Bind(pxEvt_ThreadedTaskComplete, &WaitForTaskDialog::OnTaskComplete, this); - *this += 12; - *this += Heading(m_heading).Unwrapped() | StdExpand(); - *this += 12; + *this += 12; + *this += Heading(m_heading).Unwrapped() | StdExpand(); + *this += 12; - // TODO : Implement a cancel button. Not quite sure the best way to do - // that, since it requires a thread or event handler context, or something. + // TODO : Implement a cancel button. Not quite sure the best way to do + // that, since it requires a thread or event handler context, or something. - //applyDlg += new wxButton( &applyDlg, wxID_CANCEL ) | pxCenter; - //applyDlg += 6; + //applyDlg += new wxButton( &applyDlg, wxID_CANCEL ) | pxCenter; + //applyDlg += 6; - //Bind(wxEVT_TIMER, &WaitForTaskDialog::OnTimer, this, m_Timer.GetId()); - //m_Timer.Start( 200 ); - //GetSysExecutorThread().PostEvent( new SysExecEvent_ApplyPlugins( this, m_sync ) ); + //Bind(wxEVT_TIMER, &WaitForTaskDialog::OnTimer, this, m_Timer.GetId()); + //m_Timer.Start( 200 ); + //GetSysExecutorThread().PostEvent( new SysExecEvent_ApplyPlugins( this, m_sync ) ); } -void Threading::WaitForTaskDialog::OnTaskComplete(wxCommandEvent &evt) +void Threading::WaitForTaskDialog::OnTaskComplete(wxCommandEvent& evt) { - evt.Skip(); + evt.Skip(); - // Note: we don't throw exceptions from the pending task here. - // Instead we wait until we exit the modal loop below -- this gives - // the caller a chance to handle the exception themselves, and if - // not the exception will still fall back on the standard app-level - // exception handler. + // Note: we don't throw exceptions from the pending task here. + // Instead we wait until we exit the modal loop below -- this gives + // the caller a chance to handle the exception themselves, and if + // not the exception will still fall back on the standard app-level + // exception handler. - // (this also avoids any sticky business with the modal dialog not getting - // closed out right due to stack unwinding skipping dialog closure crap) + // (this also avoids any sticky business with the modal dialog not getting + // closed out right due to stack unwinding skipping dialog closure crap) - m_sync.WaitForResult_NoExceptions(); - EndModal(wxID_OK); + m_sync.WaitForResult_NoExceptions(); + EndModal(wxID_OK); } int Threading::WaitForTaskDialog::ShowModal() { - int result = _parent::ShowModal(); - m_sync.RethrowException(); - return result; + int result = _parent::ShowModal(); + m_sync.RethrowException(); + return result; } diff --git a/common/ThreadingDialogs.h b/common/ThreadingDialogs.h index 57b152fcc9..9cd9b38237 100644 --- a/common/ThreadingDialogs.h +++ b/common/ThreadingDialogs.h @@ -22,31 +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 -{ - wxDECLARE_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 + { + wxDECLARE_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() = default; - virtual int ShowModal(); + public: + WaitForTaskDialog(const wxString& title = wxEmptyString, const wxString& heading = wxEmptyString); + virtual ~WaitForTaskDialog() = default; + virtual int ShowModal(); -protected: - void OnTaskComplete(wxCommandEvent &evt); - //void OnTimer( wxTimerEvent& evt ); -}; -} + protected: + void OnTaskComplete(wxCommandEvent& evt); + //void OnTimer( wxTimerEvent& evt ); + }; +} // namespace Threading diff --git a/common/ThreadingInternal.h b/common/ThreadingInternal.h index 12de207e89..fa1ebaccd2 100644 --- a/common/ThreadingInternal.h +++ b/common/ThreadingInternal.h @@ -21,10 +21,10 @@ namespace Threading { -extern const wxTimeSpan def_yieldgui_interval; + extern const wxTimeSpan def_yieldgui_interval; -extern bool _WaitGui_RecursionGuard(const wxChar *name); + extern bool _WaitGui_RecursionGuard(const wxChar* name); -extern void YieldToMain(); -extern bool AllowDeletions(); -} + extern void YieldToMain(); + extern bool AllowDeletions(); +} // namespace Threading diff --git a/common/TraceLog.h b/common/TraceLog.h index 45b9c922e1..a35c461f25 100644 --- a/common/TraceLog.h +++ b/common/TraceLog.h @@ -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; + } }; // -------------------------------------------------------------------------------------- @@ -66,51 +66,51 @@ struct TraceLogDescriptor 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 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 bool HasDescription() const { return m_Descriptor->Description != NULL; } }; // -------------------------------------------------------------------------------------- @@ -122,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; }; // -------------------------------------------------------------------------------------- @@ -159,130 +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); + } }; diff --git a/common/VirtualMemory.cpp b/common/VirtualMemory.cpp index 1495e424de..90086901ef 100644 --- a/common/VirtualMemory.cpp +++ b/common/VirtualMemory.cpp @@ -22,18 +22,19 @@ template class EventSource; -SrcType_PageFault *Source_PageFault = NULL; +SrcType_PageFault* Source_PageFault = NULL; Threading::Mutex PageFault_Mutex; void pxInstallSignalHandler() { - if (!Source_PageFault) { - Source_PageFault = new SrcType_PageFault(); - } + if (!Source_PageFault) + { + Source_PageFault = new SrcType_PageFault(); + } - _platform_InstallSignalHandler(); + _platform_InstallSignalHandler(); - // NOP on Win32 systems -- we use __try{} __except{} instead. + // NOP on Win32 systems -- we use __try{} __except{} instead. } // -------------------------------------------------------------------------------------- @@ -41,200 +42,221 @@ void pxInstallSignalHandler() // -------------------------------------------------------------------------------------- EventListener_PageFault::EventListener_PageFault() { - pxAssert(Source_PageFault); - Source_PageFault->Add(*this); + pxAssert(Source_PageFault); + Source_PageFault->Add(*this); } EventListener_PageFault::~EventListener_PageFault() { - if (Source_PageFault) - Source_PageFault->Remove(*this); + if (Source_PageFault) + Source_PageFault->Remove(*this); } -void SrcType_PageFault::Dispatch(const PageFaultInfo ¶ms) +void SrcType_PageFault::Dispatch(const PageFaultInfo& params) { - m_handled = false; - _parent::Dispatch(params); + m_handled = false; + _parent::Dispatch(params); } -void SrcType_PageFault::_DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const PageFaultInfo &evt) +void SrcType_PageFault::_DispatchRaw(ListenerIterator iter, const ListenerIterator& iend, const PageFaultInfo& evt) { - do { - (*iter)->DispatchEvent(evt, m_handled); - } while ((++iter != iend) && !m_handled); + do + { + (*iter)->DispatchEvent(evt, m_handled); + } while ((++iter != iend) && !m_handled); } static size_t pageAlign(size_t size) { - return (size + __pagesize - 1) / __pagesize * __pagesize; + return (size + __pagesize - 1) / __pagesize * __pagesize; } // -------------------------------------------------------------------------------------- // VirtualMemoryManager (implementations) // -------------------------------------------------------------------------------------- -VirtualMemoryManager::VirtualMemoryManager(const wxString &name, uptr base, size_t size, uptr upper_bounds, bool strict) - : m_name(name), m_baseptr(0), m_pageuse(nullptr), m_pages_reserved(0) +VirtualMemoryManager::VirtualMemoryManager(const wxString& name, uptr base, size_t size, uptr upper_bounds, bool strict) + : m_name(name) + , m_baseptr(0) + , m_pageuse(nullptr) + , m_pages_reserved(0) { - if (!size) return; + if (!size) + return; - uptr reserved_bytes = pageAlign(size); - m_pages_reserved = reserved_bytes / __pagesize; + uptr reserved_bytes = pageAlign(size); + m_pages_reserved = reserved_bytes / __pagesize; - m_baseptr = (uptr)HostSys::MmapReserve(base, reserved_bytes); + m_baseptr = (uptr)HostSys::MmapReserve(base, reserved_bytes); - if (!m_baseptr || (upper_bounds != 0 && (((uptr)m_baseptr + reserved_bytes) > upper_bounds))) { - DevCon.Warning(L"%s: host memory @ %ls -> %ls is unavailable; attempting to map elsewhere...", - WX_STR(m_name), pxsPtr(base), pxsPtr(base + size)); + if (!m_baseptr || (upper_bounds != 0 && (((uptr)m_baseptr + reserved_bytes) > upper_bounds))) + { + DevCon.Warning(L"%s: host memory @ %ls -> %ls is unavailable; attempting to map elsewhere...", + WX_STR(m_name), pxsPtr(base), pxsPtr(base + size)); - SafeSysMunmap(m_baseptr, reserved_bytes); + SafeSysMunmap(m_baseptr, reserved_bytes); - if (base) { - // Let's try again at an OS-picked memory area, and then hope it meets needed - // boundschecking criteria below. - m_baseptr = (uptr)HostSys::MmapReserve(0, reserved_bytes); - } - } + if (base) + { + // Let's try again at an OS-picked memory area, and then hope it meets needed + // boundschecking criteria below. + m_baseptr = (uptr)HostSys::MmapReserve(0, reserved_bytes); + } + } - bool fulfillsRequirements = true; - if (strict && m_baseptr != base) - fulfillsRequirements = false; - if ((upper_bounds != 0) && ((m_baseptr + reserved_bytes) > upper_bounds)) - fulfillsRequirements = false; - if (!fulfillsRequirements) { - SafeSysMunmap(m_baseptr, reserved_bytes); - } + bool fulfillsRequirements = true; + if (strict && m_baseptr != base) + fulfillsRequirements = false; + if ((upper_bounds != 0) && ((m_baseptr + reserved_bytes) > upper_bounds)) + fulfillsRequirements = false; + if (!fulfillsRequirements) + { + SafeSysMunmap(m_baseptr, reserved_bytes); + } - if (!m_baseptr) return; + if (!m_baseptr) + return; - m_pageuse = new std::atomic[m_pages_reserved](); + m_pageuse = new std::atomic[m_pages_reserved](); - FastFormatUnicode mbkb; - uint mbytes = reserved_bytes / _1mb; - if (mbytes) - mbkb.Write("[%umb]", mbytes); - else - mbkb.Write("[%ukb]", reserved_bytes / 1024); + FastFormatUnicode mbkb; + uint mbytes = reserved_bytes / _1mb; + if (mbytes) + mbkb.Write("[%umb]", mbytes); + else + mbkb.Write("[%ukb]", reserved_bytes / 1024); - DevCon.WriteLn(Color_Gray, L"%-32s @ %ls -> %ls %ls", WX_STR(m_name), - pxsPtr(m_baseptr), pxsPtr((uptr)m_baseptr + reserved_bytes), mbkb.c_str()); + DevCon.WriteLn(Color_Gray, L"%-32s @ %ls -> %ls %ls", WX_STR(m_name), + pxsPtr(m_baseptr), pxsPtr((uptr)m_baseptr + reserved_bytes), mbkb.c_str()); } VirtualMemoryManager::~VirtualMemoryManager() { - if (m_pageuse) delete[] m_pageuse; - if (m_baseptr) HostSys::Munmap(m_baseptr, m_pages_reserved * __pagesize); + if (m_pageuse) + delete[] m_pageuse; + if (m_baseptr) + HostSys::Munmap(m_baseptr, m_pages_reserved * __pagesize); } -static bool VMMMarkPagesAsInUse(std::atomic *begin, std::atomic *end) { - for (auto current = begin; current < end; current++) { - bool expected = false; - if (!current->compare_exchange_strong(expected, true), std::memory_order_relaxed) { - // This was already allocated! Undo the things we've set until this point - while (--current >= begin) { - if (!current->compare_exchange_strong(expected, false, std::memory_order_relaxed)) { - // In the time we were doing this, someone set one of the things we just set to true back to false - // This should never happen, but if it does we'll just stop and hope nothing bad happens - pxAssert(0); - return false; - } - } - return false; - } - } - return true; -} - -void *VirtualMemoryManager::Alloc(uptr offsetLocation, size_t size) const +static bool VMMMarkPagesAsInUse(std::atomic* begin, std::atomic* end) { - size = pageAlign(size); - if (!pxAssertDev(offsetLocation % __pagesize == 0, "(VirtualMemoryManager) alloc at unaligned offsetLocation")) - return nullptr; - if (!pxAssertDev(size + offsetLocation <= m_pages_reserved * __pagesize, "(VirtualMemoryManager) alloc outside reserved area")) - return nullptr; - if (m_baseptr == 0) - return nullptr; - auto puStart = &m_pageuse[offsetLocation / __pagesize]; - auto puEnd = &m_pageuse[(offsetLocation+size) / __pagesize]; - if (!pxAssertDev(VMMMarkPagesAsInUse(puStart, puEnd), "(VirtualMemoryManager) allocation requests overlapped")) - return nullptr; - return (void *)(m_baseptr + offsetLocation); + for (auto current = begin; current < end; current++) + { + bool expected = false; + if (!current->compare_exchange_strong(expected, true), std::memory_order_relaxed) + { + // This was already allocated! Undo the things we've set until this point + while (--current >= begin) + { + if (!current->compare_exchange_strong(expected, false, std::memory_order_relaxed)) + { + // In the time we were doing this, someone set one of the things we just set to true back to false + // This should never happen, but if it does we'll just stop and hope nothing bad happens + pxAssert(0); + return false; + } + } + return false; + } + } + return true; } -void VirtualMemoryManager::Free(void *address, size_t size) const +void* VirtualMemoryManager::Alloc(uptr offsetLocation, size_t size) const { - uptr offsetLocation = (uptr)address - m_baseptr; - if (!pxAssertDev(offsetLocation % __pagesize == 0, "(VirtualMemoryManager) free at unaligned address")) { - uptr newLoc = pageAlign(offsetLocation); - size -= (offsetLocation - newLoc); - offsetLocation = newLoc; - } - if (!pxAssertDev(size % __pagesize == 0, "(VirtualMemoryManager) free with unaligned size")) - size -= size % __pagesize; - if (!pxAssertDev(size + offsetLocation <= m_pages_reserved * __pagesize, "(VirtualMemoryManager) free outside reserved area")) - return; - auto puStart = &m_pageuse[offsetLocation / __pagesize]; - auto puEnd = &m_pageuse[(offsetLocation+size) / __pagesize]; - for (; puStart < puEnd; puStart++) { - bool expected = true; - if (!puStart->compare_exchange_strong(expected, false, std::memory_order_relaxed)) { - pxAssertDev(0, "(VirtaulMemoryManager) double-free"); - } - } + size = pageAlign(size); + if (!pxAssertDev(offsetLocation % __pagesize == 0, "(VirtualMemoryManager) alloc at unaligned offsetLocation")) + return nullptr; + if (!pxAssertDev(size + offsetLocation <= m_pages_reserved * __pagesize, "(VirtualMemoryManager) alloc outside reserved area")) + return nullptr; + if (m_baseptr == 0) + return nullptr; + auto puStart = &m_pageuse[offsetLocation / __pagesize]; + auto puEnd = &m_pageuse[(offsetLocation + size) / __pagesize]; + if (!pxAssertDev(VMMMarkPagesAsInUse(puStart, puEnd), "(VirtualMemoryManager) allocation requests overlapped")) + return nullptr; + return (void*)(m_baseptr + offsetLocation); +} + +void VirtualMemoryManager::Free(void* address, size_t size) const +{ + uptr offsetLocation = (uptr)address - m_baseptr; + if (!pxAssertDev(offsetLocation % __pagesize == 0, "(VirtualMemoryManager) free at unaligned address")) + { + uptr newLoc = pageAlign(offsetLocation); + size -= (offsetLocation - newLoc); + offsetLocation = newLoc; + } + if (!pxAssertDev(size % __pagesize == 0, "(VirtualMemoryManager) free with unaligned size")) + size -= size % __pagesize; + if (!pxAssertDev(size + offsetLocation <= m_pages_reserved * __pagesize, "(VirtualMemoryManager) free outside reserved area")) + return; + auto puStart = &m_pageuse[offsetLocation / __pagesize]; + auto puEnd = &m_pageuse[(offsetLocation + size) / __pagesize]; + for (; puStart < puEnd; puStart++) + { + bool expected = true; + if (!puStart->compare_exchange_strong(expected, false, std::memory_order_relaxed)) + { + pxAssertDev(0, "(VirtaulMemoryManager) double-free"); + } + } } // -------------------------------------------------------------------------------------- // VirtualMemoryBumpAllocator (implementations) // -------------------------------------------------------------------------------------- VirtualMemoryBumpAllocator::VirtualMemoryBumpAllocator(VirtualMemoryManagerPtr allocator, uptr offsetLocation, size_t size) - : m_allocator(std::move(allocator)), m_baseptr((uptr)m_allocator->Alloc(offsetLocation, size)), m_endptr(m_baseptr + size) + : m_allocator(std::move(allocator)) + , m_baseptr((uptr)m_allocator->Alloc(offsetLocation, size)) + , m_endptr(m_baseptr + size) { - if (m_baseptr.load() == 0) - pxAssertDev(0, "(VirtualMemoryBumpAllocator) tried to construct from bad VirtualMemoryManager"); + if (m_baseptr.load() == 0) + pxAssertDev(0, "(VirtualMemoryBumpAllocator) tried to construct from bad VirtualMemoryManager"); } -void *VirtualMemoryBumpAllocator::Alloc(size_t size) +void* VirtualMemoryBumpAllocator::Alloc(size_t size) { - if (m_baseptr.load() == 0) // True if constructed from bad VirtualMemoryManager (assertion was on initialization) - return nullptr; + if (m_baseptr.load() == 0) // True if constructed from bad VirtualMemoryManager (assertion was on initialization) + return nullptr; - size_t reservedSize = pageAlign(size); + size_t reservedSize = pageAlign(size); - uptr out = m_baseptr.fetch_add(reservedSize, std::memory_order_relaxed); + uptr out = m_baseptr.fetch_add(reservedSize, std::memory_order_relaxed); - if (!pxAssertDev(out - reservedSize + size <= m_endptr, "(VirtualMemoryBumpAllocator) ran out of memory")) - return nullptr; + if (!pxAssertDev(out - reservedSize + size <= m_endptr, "(VirtualMemoryBumpAllocator) ran out of memory")) + return nullptr; - return (void *)out; + return (void*)out; } // -------------------------------------------------------------------------------------- // VirtualMemoryReserve (implementations) // -------------------------------------------------------------------------------------- -VirtualMemoryReserve::VirtualMemoryReserve(const wxString &name, size_t size) - : m_name(name) +VirtualMemoryReserve::VirtualMemoryReserve(const wxString& name, size_t size) + : m_name(name) { - m_defsize = size; + m_defsize = size; - m_allocator = nullptr; - m_pages_commited = 0; - m_pages_reserved = 0; - m_baseptr = nullptr; - m_prot_mode = PageAccess_None(); - m_allow_writes = true; + m_allocator = nullptr; + m_pages_commited = 0; + m_pages_reserved = 0; + m_baseptr = nullptr; + m_prot_mode = PageAccess_None(); + m_allow_writes = true; } -VirtualMemoryReserve &VirtualMemoryReserve::SetPageAccessOnCommit(const PageProtectionMode &mode) +VirtualMemoryReserve& VirtualMemoryReserve::SetPageAccessOnCommit(const PageProtectionMode& mode) { - m_prot_mode = mode; - return *this; + m_prot_mode = mode; + return *this; } size_t VirtualMemoryReserve::GetSize(size_t requestedSize) { - if (!requestedSize) - return pageAlign(m_defsize); - return pageAlign(requestedSize); + if (!requestedSize) + return pageAlign(m_defsize); + return pageAlign(requestedSize); } // Notes: @@ -245,84 +267,85 @@ size_t VirtualMemoryReserve::GetSize(size_t requestedSize) // baseptr - the new base pointer that's about to be assigned // size - size of the region pointed to by baseptr // -void *VirtualMemoryReserve::Assign(VirtualMemoryManagerPtr allocator, void * baseptr, size_t size) +void* VirtualMemoryReserve::Assign(VirtualMemoryManagerPtr allocator, void* baseptr, size_t size) { - if (!pxAssertDev(m_baseptr == NULL, "(VirtualMemoryReserve) Invalid object state; object has already been reserved.")) - return m_baseptr; + if (!pxAssertDev(m_baseptr == NULL, "(VirtualMemoryReserve) Invalid object state; object has already been reserved.")) + return m_baseptr; - if (!size) - return nullptr; + if (!size) + return nullptr; - m_allocator = std::move(allocator); + m_allocator = std::move(allocator); - m_baseptr = baseptr; + m_baseptr = baseptr; - uptr reserved_bytes = pageAlign(size); - m_pages_reserved = reserved_bytes / __pagesize; + uptr reserved_bytes = pageAlign(size); + m_pages_reserved = reserved_bytes / __pagesize; - if (!m_baseptr) - return nullptr; + if (!m_baseptr) + return nullptr; - FastFormatUnicode mbkb; - uint mbytes = reserved_bytes / _1mb; - if (mbytes) - mbkb.Write("[%umb]", mbytes); - else - mbkb.Write("[%ukb]", reserved_bytes / 1024); + FastFormatUnicode mbkb; + uint mbytes = reserved_bytes / _1mb; + if (mbytes) + mbkb.Write("[%umb]", mbytes); + else + mbkb.Write("[%ukb]", reserved_bytes / 1024); - DevCon.WriteLn(Color_Gray, L"%-32s @ %ls -> %ls %ls", WX_STR(m_name), - pxsPtr(m_baseptr), pxsPtr((uptr)m_baseptr + reserved_bytes), mbkb.c_str()); + DevCon.WriteLn(Color_Gray, L"%-32s @ %ls -> %ls %ls", WX_STR(m_name), + pxsPtr(m_baseptr), pxsPtr((uptr)m_baseptr + reserved_bytes), mbkb.c_str()); - return m_baseptr; + return m_baseptr; } -void VirtualMemoryReserve::ReprotectCommittedBlocks(const PageProtectionMode &newmode) +void VirtualMemoryReserve::ReprotectCommittedBlocks(const PageProtectionMode& newmode) { - if (!m_pages_commited) - return; - HostSys::MemProtect(m_baseptr, m_pages_commited * __pagesize, newmode); + if (!m_pages_commited) + return; + HostSys::MemProtect(m_baseptr, m_pages_commited * __pagesize, newmode); } // Clears all committed blocks, restoring the allocation to a reserve only. void VirtualMemoryReserve::Reset() { - if (!m_pages_commited) - return; + if (!m_pages_commited) + return; - ReprotectCommittedBlocks(PageAccess_None()); - HostSys::MmapResetPtr(m_baseptr, m_pages_commited * __pagesize); - m_pages_commited = 0; + ReprotectCommittedBlocks(PageAccess_None()); + HostSys::MmapResetPtr(m_baseptr, m_pages_commited * __pagesize); + m_pages_commited = 0; } void VirtualMemoryReserve::Release() { - if (!m_baseptr) return; - Reset(); - m_allocator->Free(m_baseptr, m_pages_reserved * __pagesize); - m_baseptr = nullptr; + if (!m_baseptr) + return; + Reset(); + m_allocator->Free(m_baseptr, m_pages_reserved * __pagesize); + m_baseptr = nullptr; } bool VirtualMemoryReserve::Commit() { - if (!m_pages_reserved) - return false; - if (!pxAssert(!m_pages_commited)) - return true; + if (!m_pages_reserved) + return false; + if (!pxAssert(!m_pages_commited)) + return true; - m_pages_commited = m_pages_reserved; - return HostSys::MmapCommitPtr(m_baseptr, m_pages_reserved * __pagesize, m_prot_mode); + m_pages_commited = m_pages_reserved; + return HostSys::MmapCommitPtr(m_baseptr, m_pages_reserved * __pagesize, m_prot_mode); } void VirtualMemoryReserve::AllowModification() { - m_allow_writes = true; - HostSys::MemProtect(m_baseptr, m_pages_commited * __pagesize, m_prot_mode); + m_allow_writes = true; + HostSys::MemProtect(m_baseptr, m_pages_commited * __pagesize, m_prot_mode); } void VirtualMemoryReserve::ForbidModification() { - m_allow_writes = false; - HostSys::MemProtect(m_baseptr, m_pages_commited * __pagesize, PageProtectionMode(m_prot_mode).Write(false)); + m_allow_writes = false; + HostSys::MemProtect(m_baseptr, m_pages_commited * __pagesize, PageProtectionMode(m_prot_mode).Write(false)); } @@ -337,39 +360,43 @@ void VirtualMemoryReserve::ForbidModification() // newsize - new size of the reserved buffer, in bytes. bool VirtualMemoryReserve::TryResize(uint newsize) { - uint newPages = pageAlign(newsize) / __pagesize; + uint newPages = pageAlign(newsize) / __pagesize; - if (newPages > m_pages_reserved) { - uint toReservePages = newPages - m_pages_reserved; - uint toReserveBytes = toReservePages * __pagesize; + if (newPages > m_pages_reserved) + { + uint toReservePages = newPages - m_pages_reserved; + uint toReserveBytes = toReservePages * __pagesize; - DevCon.WriteLn(L"%-32s is being expanded by %u pages.", WX_STR(m_name), toReservePages); + DevCon.WriteLn(L"%-32s is being expanded by %u pages.", WX_STR(m_name), toReservePages); - if (!m_allocator->AllocAtAddress(GetPtrEnd(), toReserveBytes)) { - Console.Warning("%-32s could not be passively resized due to virtual memory conflict!", WX_STR(m_name)); - Console.Indent().Warning("(attempted to map memory @ %08p -> %08p)", m_baseptr, (uptr)m_baseptr + toReserveBytes); - return false; - } + if (!m_allocator->AllocAtAddress(GetPtrEnd(), toReserveBytes)) + { + Console.Warning("%-32s could not be passively resized due to virtual memory conflict!", WX_STR(m_name)); + Console.Indent().Warning("(attempted to map memory @ %08p -> %08p)", m_baseptr, (uptr)m_baseptr + toReserveBytes); + return false; + } - DevCon.WriteLn(Color_Gray, L"%-32s @ %08p -> %08p [%umb]", WX_STR(m_name), - m_baseptr, (uptr)m_baseptr + toReserveBytes, toReserveBytes / _1mb); - } else if (newPages < m_pages_reserved) { - if (m_pages_commited > newsize) - return false; + DevCon.WriteLn(Color_Gray, L"%-32s @ %08p -> %08p [%umb]", WX_STR(m_name), + m_baseptr, (uptr)m_baseptr + toReserveBytes, toReserveBytes / _1mb); + } + else if (newPages < m_pages_reserved) + { + if (m_pages_commited > newsize) + return false; - uint toRemovePages = m_pages_reserved - newPages; - uint toRemoveBytes = toRemovePages * __pagesize; + uint toRemovePages = m_pages_reserved - newPages; + uint toRemoveBytes = toRemovePages * __pagesize; - DevCon.WriteLn(L"%-32s is being shrunk by %u pages.", WX_STR(m_name), toRemovePages); + DevCon.WriteLn(L"%-32s is being shrunk by %u pages.", WX_STR(m_name), toRemovePages); - m_allocator->Free(GetPtrEnd() - toRemoveBytes, toRemoveBytes); + m_allocator->Free(GetPtrEnd() - toRemoveBytes, toRemoveBytes); - DevCon.WriteLn(Color_Gray, L"%-32s @ %08p -> %08p [%umb]", WX_STR(m_name), - m_baseptr, GetPtrEnd(), GetReserveSizeInBytes() / _1mb); - } + DevCon.WriteLn(Color_Gray, L"%-32s @ %08p -> %08p [%umb]", WX_STR(m_name), + m_baseptr, GetPtrEnd(), GetReserveSizeInBytes() / _1mb); + } - m_pages_reserved = newPages; - return true; + m_pages_reserved = newPages; + return true; } // -------------------------------------------------------------------------------------- @@ -377,27 +404,27 @@ bool VirtualMemoryReserve::TryResize(uint newsize) // -------------------------------------------------------------------------------------- wxString PageProtectionMode::ToString() const { - wxString modeStr; + wxString modeStr; - if (m_read) - modeStr += L"Read"; - if (m_write) - modeStr += L"Write"; - if (m_exec) - modeStr += L"Exec"; + if (m_read) + modeStr += L"Read"; + if (m_write) + modeStr += L"Write"; + if (m_exec) + modeStr += L"Exec"; - if (modeStr.IsEmpty()) - return L"NoAccess"; - if (modeStr.Length() <= 5) - modeStr += L"Only"; + if (modeStr.IsEmpty()) + return L"NoAccess"; + if (modeStr.Length() <= 5) + modeStr += L"Only"; - return modeStr; + return modeStr; } // -------------------------------------------------------------------------------------- // Common HostSys implementation // -------------------------------------------------------------------------------------- -void HostSys::Munmap(void *base, size_t size) +void HostSys::Munmap(void* base, size_t size) { - Munmap((uptr)base, size); + Munmap((uptr)base, size); } diff --git a/common/Windows/WinHostSys.cpp b/common/Windows/WinHostSys.cpp index eeec61ee7c..85be0f9f7b 100644 --- a/common/Windows/WinHostSys.cpp +++ b/common/Windows/WinHostSys.cpp @@ -18,136 +18,146 @@ #include "common/RedtapeWindows.h" #include "common/PageFaultSource.h" -static long DoSysPageFaultExceptionFilter(EXCEPTION_POINTERS *eps) +static long DoSysPageFaultExceptionFilter(EXCEPTION_POINTERS* eps) { - if (eps->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) - return EXCEPTION_CONTINUE_SEARCH; + if (eps->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) + return EXCEPTION_CONTINUE_SEARCH; - // Note: This exception 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)eps->ExceptionRecord->ExceptionInformation[1])); - return Source_PageFault->WasHandled() ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH; + // Note: This exception 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)eps->ExceptionRecord->ExceptionInformation[1])); + return Source_PageFault->WasHandled() ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH; } -long __stdcall SysPageFaultExceptionFilter(EXCEPTION_POINTERS *eps) +long __stdcall SysPageFaultExceptionFilter(EXCEPTION_POINTERS* eps) { - // Prevent recursive exception filtering by catching the exception from the filter here. - // In the event that the filter causes an access violation (happened during shutdown - // because Source_PageFault was deallocated), this will allow the debugger to catch the - // exception. - // TODO: find a reliable way to debug the filter itself, I've come up with a few ways that - // work but I don't fully understand why some do and some don't. - __try { - return DoSysPageFaultExceptionFilter(eps); - } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { - return EXCEPTION_CONTINUE_SEARCH; - } + // Prevent recursive exception filtering by catching the exception from the filter here. + // In the event that the filter causes an access violation (happened during shutdown + // because Source_PageFault was deallocated), this will allow the debugger to catch the + // exception. + // TODO: find a reliable way to debug the filter itself, I've come up with a few ways that + // work but I don't fully understand why some do and some don't. + __try + { + return DoSysPageFaultExceptionFilter(eps); + } + __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { + return EXCEPTION_CONTINUE_SEARCH; + } } void _platform_InstallSignalHandler() { #ifdef _WIN64 // We don't handle SEH properly on Win64 so use a vectored exception handler instead - AddVectoredExceptionHandler(true, SysPageFaultExceptionFilter); + AddVectoredExceptionHandler(true, SysPageFaultExceptionFilter); #endif } -static DWORD ConvertToWinApi(const PageProtectionMode &mode) +static DWORD ConvertToWinApi(const PageProtectionMode& mode) { - DWORD winmode = PAGE_NOACCESS; + DWORD winmode = PAGE_NOACCESS; - // Windows has some really bizarre memory protection enumeration that uses bitwise - // numbering (like flags) but is in fact not a flag value. *Someone* from the early - // microsoft days wasn't a very good coder, me thinks. --air + // Windows has some really bizarre memory protection enumeration that uses bitwise + // numbering (like flags) but is in fact not a flag value. *Someone* from the early + // microsoft days wasn't a very good coder, me thinks. --air - if (mode.CanExecute()) { - winmode = mode.CanWrite() ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; - } else if (mode.CanRead()) { - winmode = mode.CanWrite() ? PAGE_READWRITE : PAGE_READONLY; - } + if (mode.CanExecute()) + { + winmode = mode.CanWrite() ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; + } + else if (mode.CanRead()) + { + winmode = mode.CanWrite() ? PAGE_READWRITE : PAGE_READONLY; + } - return winmode; + return winmode; } -void *HostSys::MmapReservePtr(void *base, size_t size) +void* HostSys::MmapReservePtr(void* base, size_t size) { - return VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS); + return VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS); } -bool HostSys::MmapCommitPtr(void *base, size_t size, const PageProtectionMode &mode) +bool HostSys::MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode) { - void *result = VirtualAlloc(base, size, MEM_COMMIT, ConvertToWinApi(mode)); - if (result) - return true; + void* result = VirtualAlloc(base, size, MEM_COMMIT, ConvertToWinApi(mode)); + if (result) + return true; - const DWORD errcode = GetLastError(); - if (errcode == ERROR_COMMITMENT_MINIMUM) { - Console.Warning("(MmapCommit) Received windows error %u {Virtual Memory Minimum Too Low}.", ERROR_COMMITMENT_MINIMUM); - Sleep(1000); // Cut windows some time to rework its memory... - } else if (errcode != ERROR_NOT_ENOUGH_MEMORY && errcode != ERROR_OUTOFMEMORY) { - pxFailDev(L"VirtualAlloc COMMIT failed: " + Exception::WinApiError().GetMsgFromWindows()); - return false; - } + const DWORD errcode = GetLastError(); + if (errcode == ERROR_COMMITMENT_MINIMUM) + { + Console.Warning("(MmapCommit) Received windows error %u {Virtual Memory Minimum Too Low}.", ERROR_COMMITMENT_MINIMUM); + Sleep(1000); // Cut windows some time to rework its memory... + } + else if (errcode != ERROR_NOT_ENOUGH_MEMORY && errcode != ERROR_OUTOFMEMORY) + { + pxFailDev(L"VirtualAlloc COMMIT failed: " + Exception::WinApiError().GetMsgFromWindows()); + return false; + } - if (!pxDoOutOfMemory) - return false; - pxDoOutOfMemory(size); - return VirtualAlloc(base, size, MEM_COMMIT, ConvertToWinApi(mode)) != NULL; + if (!pxDoOutOfMemory) + return false; + pxDoOutOfMemory(size); + return VirtualAlloc(base, size, MEM_COMMIT, ConvertToWinApi(mode)) != NULL; } -void HostSys::MmapResetPtr(void *base, size_t size) +void HostSys::MmapResetPtr(void* base, size_t size) { - VirtualFree(base, size, MEM_DECOMMIT); + VirtualFree(base, size, MEM_DECOMMIT); } -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) { - return VirtualAlloc((void *)base, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); + return VirtualAlloc((void*)base, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); } void HostSys::Munmap(uptr base, size_t size) { - if (!base) - return; - //VirtualFree((void*)base, size, MEM_DECOMMIT); - VirtualFree((void *)base, 0, MEM_RELEASE); + if (!base) + return; + //VirtualFree((void*)base, size, MEM_DECOMMIT); + VirtualFree((void*)base, 0, MEM_RELEASE); } -void HostSys::MemProtect(void *baseaddr, size_t size, const PageProtectionMode &mode) +void HostSys::MemProtect(void* baseaddr, size_t size, const PageProtectionMode& mode) { - 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%04x (%d), Block Size: 0x%04x (%d)", - __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%04x (%d), Block Size: 0x%04x (%d)", + __pagesize, __pagesize, size, size)); - DWORD OldProtect; // enjoy my uselessness, yo! - if (!VirtualProtect(baseaddr, size, ConvertToWinApi(mode), &OldProtect)) { - Exception::WinApiError apiError; + DWORD OldProtect; // enjoy my uselessness, yo! + if (!VirtualProtect(baseaddr, size, ConvertToWinApi(mode), &OldProtect)) + { + Exception::WinApiError apiError; - apiError.SetDiagMsg( - pxsFmt(L"VirtualProtect failed @ 0x%08X -> 0x%08X (mode=%s)", - baseaddr, (uptr)baseaddr + size, mode.ToString().c_str())); + apiError.SetDiagMsg( + pxsFmt(L"VirtualProtect failed @ 0x%08X -> 0x%08X (mode=%s)", + baseaddr, (uptr)baseaddr + size, mode.ToString().c_str())); - pxFailDev(apiError.FormatDiagnosticMessage()); - } + pxFailDev(apiError.FormatDiagnosticMessage()); + } } #endif diff --git a/common/Windows/WinThreads.cpp b/common/Windows/WinThreads.cpp index 05e93e3eb9..a4a6cb377d 100644 --- a/common/Windows/WinThreads.cpp +++ b/common/Windows/WinThreads.cpp @@ -21,115 +21,118 @@ __fi void Threading::Sleep(int ms) { - ::Sleep(ms); + ::Sleep(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. __fi void Threading::SpinWait() { - _mm_pause(); + _mm_pause(); } __fi void Threading::EnableHiresScheduler() { - // This improves accuracy of Sleep() by some amount, and only adds a negligible amount of - // overhead on modern CPUs. Typically desktops are already set pretty low, but laptops in - // particular may have a scheduler Period of 15 or 20ms to extend battery life. + // This improves accuracy of Sleep() by some amount, and only adds a negligible amount of + // overhead on modern CPUs. Typically desktops are already set pretty low, but laptops in + // particular may have a scheduler Period of 15 or 20ms to extend battery life. - // (note: this same trick is used by most multimedia software and games) + // (note: this same trick is used by most multimedia software and games) - timeBeginPeriod(1); + timeBeginPeriod(1); } __fi void Threading::DisableHiresScheduler() { - timeEndPeriod(1); + timeEndPeriod(1); } // This hacky union would probably fail on some cpu platforms if the contents of FILETIME aren't // packed (but for any x86 CPU and microsoft compiler, they will be). union FileTimeSucks { - FILETIME filetime; - u64 u64time; + FILETIME filetime; + u64 u64time; }; u64 Threading::GetThreadCpuTime() { - FileTimeSucks user, kernel; - FILETIME dummy; - GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel.filetime, &user.filetime); - return user.u64time + kernel.u64time; + FileTimeSucks user, kernel; + FILETIME dummy; + GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel.filetime, &user.filetime); + return user.u64time + kernel.u64time; } u64 Threading::GetThreadTicksPerSecond() { - return 10000000; + return 10000000; } u64 Threading::pxThread::GetCpuTime() const { - if (!m_native_handle) - return 0; + if (!m_native_handle) + return 0; - FileTimeSucks user, kernel; - FILETIME dummy; + FileTimeSucks user, kernel; + FILETIME dummy; - if (GetThreadTimes((HANDLE)m_native_handle, &dummy, &dummy, &kernel.filetime, &user.filetime)) - return user.u64time + kernel.u64time; + if (GetThreadTimes((HANDLE)m_native_handle, &dummy, &dummy, &kernel.filetime, &user.filetime)) + return user.u64time + kernel.u64time; - return 0; // thread prolly doesn't exist anymore. + return 0; // thread prolly doesn't exist anymore. } void Threading::pxThread::_platform_specific_OnStartInThread() { - // OpenThread Note: Vista and Win7 need only THREAD_QUERY_LIMITED_INFORMATION (XP and 2k need more), - // however we own our process threads, so shouldn't matter in any case... + // OpenThread Note: Vista and Win7 need only THREAD_QUERY_LIMITED_INFORMATION (XP and 2k need more), + // however we own our process threads, so shouldn't matter in any case... - m_native_id = (uptr)GetCurrentThreadId(); - m_native_handle = (uptr)OpenThread(THREAD_QUERY_INFORMATION, false, (DWORD)m_native_id); + m_native_id = (uptr)GetCurrentThreadId(); + m_native_handle = (uptr)OpenThread(THREAD_QUERY_INFORMATION, false, (DWORD)m_native_id); - pxAssertDev(m_native_handle, wxNullChar); + pxAssertDev(m_native_handle, wxNullChar); } void Threading::pxThread::_platform_specific_OnCleanupInThread() { - CloseHandle((HANDLE)m_native_handle); + CloseHandle((HANDLE)m_native_handle); } -void Threading::SetNameOfCurrentThread(const char *name) +void Threading::SetNameOfCurrentThread(const char* name) { -// This feature needs Windows headers and MSVC's SEH support: + // This feature needs Windows headers and MSVC's SEH support: #if defined(_WIN32) && defined(_MSC_VER) - // This code sample was borrowed form some obscure MSDN article. - // In a rare bout of sanity, it's an actual Microsoft-published hack - // that actually works! + // This code sample was borrowed form some obscure MSDN article. + // In a rare bout of sanity, it's an actual Microsoft-published hack + // that actually works! - static const int MS_VC_EXCEPTION = 0x406D1388; + static const int MS_VC_EXCEPTION = 0x406D1388; #pragma pack(push, 8) - struct THREADNAME_INFO - { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. - }; + struct THREADNAME_INFO + { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. + }; #pragma pack(pop) - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = name; - info.dwThreadID = GetCurrentThreadId(); - info.dwFlags = 0; + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = name; + info.dwThreadID = GetCurrentThreadId(); + info.dwFlags = 0; - __try { - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info); - } __except (EXCEPTION_EXECUTE_HANDLER) { - } + __try + { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } #endif } diff --git a/common/emitter/LnxCpuDetect.cpp b/common/emitter/LnxCpuDetect.cpp index 9100e486a0..80ea32027c 100644 --- a/common/emitter/LnxCpuDetect.cpp +++ b/common/emitter/LnxCpuDetect.cpp @@ -21,10 +21,10 @@ // FreeBSD/OsX need something far more complicated (apparently) void x86capabilities::CountLogicalCores() { - // Note : GetCPUCount uses sysconf( _SC_NPROCESSORS_ONLN ) internally, which can return 1 - // if sysconf info isn't available (a long standing linux bug). There are no fallbacks or - // alternatives, apparently. - LogicalCores = wxThread::GetCPUCount(); + // Note : GetCPUCount uses sysconf( _SC_NPROCESSORS_ONLN ) internally, which can return 1 + // if sysconf info isn't available (a long standing linux bug). There are no fallbacks or + // alternatives, apparently. + LogicalCores = wxThread::GetCPUCount(); } // Not implemented yet for linux (see cpudetect_internal.h for details) diff --git a/common/emitter/WinCpuDetect.cpp b/common/emitter/WinCpuDetect.cpp index e5f3e4dab9..e1f947cc2a 100644 --- a/common/emitter/WinCpuDetect.cpp +++ b/common/emitter/WinCpuDetect.cpp @@ -20,65 +20,66 @@ void x86capabilities::CountLogicalCores() { - DWORD_PTR vProcessCPUs; - DWORD_PTR vSystemCPUs; + DWORD_PTR vProcessCPUs; + DWORD_PTR vSystemCPUs; - LogicalCores = 1; + LogicalCores = 1; - if (!GetProcessAffinityMask(GetCurrentProcess(), &vProcessCPUs, &vSystemCPUs)) - return; + if (!GetProcessAffinityMask(GetCurrentProcess(), &vProcessCPUs, &vSystemCPUs)) + return; - uint CPUs = 0; - for (DWORD_PTR bit = 1; bit != 0; bit <<= 1) - if (vSystemCPUs & bit) - CPUs++; + uint CPUs = 0; + for (DWORD_PTR bit = 1; bit != 0; bit <<= 1) + if (vSystemCPUs & bit) + CPUs++; - LogicalCores = CPUs; + LogicalCores = CPUs; } SingleCoreAffinity::SingleCoreAffinity() { - s_threadId = nullptr; - s_oldmask = ERROR_INVALID_PARAMETER; + s_threadId = nullptr; + s_oldmask = ERROR_INVALID_PARAMETER; - DWORD_PTR availProcCpus; - DWORD_PTR availSysCpus; - if (!GetProcessAffinityMask(GetCurrentProcess(), &availProcCpus, &availSysCpus)) - return; + DWORD_PTR availProcCpus; + DWORD_PTR availSysCpus; + if (!GetProcessAffinityMask(GetCurrentProcess(), &availProcCpus, &availSysCpus)) + return; - int cpu = 0; - DWORD_PTR affinityMask; - for (affinityMask = 1; affinityMask != 0; affinityMask <<= 1, ++cpu) - if (availProcCpus & affinityMask) - break; + int cpu = 0; + DWORD_PTR affinityMask; + for (affinityMask = 1; affinityMask != 0; affinityMask <<= 1, ++cpu) + if (availProcCpus & affinityMask) + break; - s_threadId = GetCurrentThread(); - s_oldmask = SetThreadAffinityMask(s_threadId, affinityMask); + s_threadId = GetCurrentThread(); + s_oldmask = SetThreadAffinityMask(s_threadId, affinityMask); - if (s_oldmask == ERROR_INVALID_PARAMETER) { - const int hexWidth = 2 * sizeof(DWORD_PTR); - Console.Warning( - "CpuDetect: SetThreadAffinityMask failed...\n" - "\tSystem Affinity : 0x%0*x\n" - "\tProcess Affinity: 0x%0*x\n" - "\tAttempted Thread Affinity CPU: %i", - hexWidth, availProcCpus, hexWidth, availSysCpus, cpu); - } + if (s_oldmask == ERROR_INVALID_PARAMETER) + { + const int hexWidth = 2 * sizeof(DWORD_PTR); + Console.Warning( + "CpuDetect: SetThreadAffinityMask failed...\n" + "\tSystem Affinity : 0x%0*x\n" + "\tProcess Affinity: 0x%0*x\n" + "\tAttempted Thread Affinity CPU: %i", + hexWidth, availProcCpus, hexWidth, availSysCpus, cpu); + } - Sleep(2); + Sleep(2); - // Sleep Explained: I arbitrarily pick Core 0 to lock to for running the CPU test. This - // means that the current thread will need to be switched to Core 0 if it's currently - // scheduled on a difference cpu/core. However, Windows does not necessarily perform - // that scheduling immediately upon the call to SetThreadAffinityMask (seems dependent - // on version: XP does, Win7 does not). So by issuing a Sleep here we give Win7 time - // to issue a timeslice and move our thread to Core 0. Without this, it tends to move - // the thread during the cpuSpeed test instead, causing totally wacky results. + // Sleep Explained: I arbitrarily pick Core 0 to lock to for running the CPU test. This + // means that the current thread will need to be switched to Core 0 if it's currently + // scheduled on a difference cpu/core. However, Windows does not necessarily perform + // that scheduling immediately upon the call to SetThreadAffinityMask (seems dependent + // on version: XP does, Win7 does not). So by issuing a Sleep here we give Win7 time + // to issue a timeslice and move our thread to Core 0. Without this, it tends to move + // the thread during the cpuSpeed test instead, causing totally wacky results. }; SingleCoreAffinity::~SingleCoreAffinity() { - if (s_oldmask != ERROR_INVALID_PARAMETER) - SetThreadAffinityMask(s_threadId, s_oldmask); + if (s_oldmask != ERROR_INVALID_PARAMETER) + SetThreadAffinityMask(s_threadId, s_oldmask); } #endif diff --git a/common/emitter/bmi.cpp b/common/emitter/bmi.cpp index d1ce6a2db7..8c9ea9a809 100644 --- a/common/emitter/bmi.cpp +++ b/common/emitter/bmi.cpp @@ -19,17 +19,17 @@ namespace x86Emitter { -const xImplBMI_RVM xMULX = {0xF2, 0x38, 0xF6}; -const xImplBMI_RVM xPDEP = {0xF2, 0x38, 0xF5}; -const xImplBMI_RVM xPEXT = {0xF3, 0x38, 0xF5}; -const xImplBMI_RVM xANDN_S = {0x00, 0x38, 0xF2}; + const xImplBMI_RVM xMULX = {0xF2, 0x38, 0xF6}; + const xImplBMI_RVM xPDEP = {0xF2, 0x38, 0xF5}; + const xImplBMI_RVM xPEXT = {0xF3, 0x38, 0xF5}; + const xImplBMI_RVM xANDN_S = {0x00, 0x38, 0xF2}; -void xImplBMI_RVM::operator()(const xRegisterInt &to, const xRegisterInt &from1, const xRegisterInt &from2) const -{ - xOpWriteC4(Prefix, MbPrefix, Opcode, to, from1, from2); -} -void xImplBMI_RVM::operator()(const xRegisterInt &to, const xRegisterInt &from1, const xIndirectVoid &from2) const -{ - xOpWriteC4(Prefix, MbPrefix, Opcode, to, from1, from2); -} -} + void xImplBMI_RVM::operator()(const xRegisterInt& to, const xRegisterInt& from1, const xRegisterInt& from2) const + { + xOpWriteC4(Prefix, MbPrefix, Opcode, to, from1, from2); + } + void xImplBMI_RVM::operator()(const xRegisterInt& to, const xRegisterInt& from1, const xIndirectVoid& from2) const + { + xOpWriteC4(Prefix, MbPrefix, Opcode, to, from1, from2); + } +} // namespace x86Emitter diff --git a/common/emitter/cpudetect.cpp b/common/emitter/cpudetect.cpp index ec8beccddb..6cdf427c9f 100644 --- a/common/emitter/cpudetect.cpp +++ b/common/emitter/cpudetect.cpp @@ -31,12 +31,12 @@ 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]); + __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]); + __cpuid(InfoType, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]); } #endif @@ -46,23 +46,23 @@ using namespace x86Emitter; __aligned16 x86capabilities x86caps; x86capabilities::x86capabilities() - : isIdentified(false) - , VendorID(x86Vendor_Unknown) - , FamilyID(0) - , Model(0) - , TypeID(0) - , StepID(0) - , Flags(0) - , Flags2(0) - , EFlags(0) - , EFlags2(0) - , SEFlag(0) - , AllCapabilities(0) - , PhysicalCores(0) - , LogicalCores(0) + : isIdentified(false) + , VendorID(x86Vendor_Unknown) + , FamilyID(0) + , Model(0) + , TypeID(0) + , StepID(0) + , Flags(0) + , Flags2(0) + , EFlags(0) + , EFlags2(0) + , SEFlag(0) + , AllCapabilities(0) + , PhysicalCores(0) + , LogicalCores(0) { - memzero(VendorName); - memzero(FamilyName); + memzero(VendorName); + memzero(FamilyName); } // Warning! We've had problems with the MXCSR detection code causing stack corruption in @@ -72,28 +72,29 @@ x86capabilities::x86capabilities() // Note: recSSE was deleted void x86capabilities::SIMD_EstablishMXCSRmask() { - if (!hasStreamingSIMDExtensions) - return; + if (!hasStreamingSIMDExtensions) + return; - MXCSR_Mask.bitmask = 0xFFBF; // MMX/SSE default + MXCSR_Mask.bitmask = 0xFFBF; // MMX/SSE default - if (hasStreamingSIMD2Extensions) { - // This is generally safe assumption, but FXSAVE is the "correct" way to - // detect MXCSR masking features of the cpu, so we use it's result below - // and override this. + if (hasStreamingSIMD2Extensions) + { + // This is generally safe assumption, but FXSAVE is the "correct" way to + // detect MXCSR masking features of the cpu, so we use it's result below + // and override this. - MXCSR_Mask.bitmask = 0xFFFF; // SSE2 features added - } + MXCSR_Mask.bitmask = 0xFFFF; // SSE2 features added + } - __aligned16 u8 targetFXSAVE[512]; + __aligned16 u8 targetFXSAVE[512]; - // Work for recent enough GCC/CLANG/MSVC 2012 - _fxsave(&targetFXSAVE); + // Work for recent enough GCC/CLANG/MSVC 2012 + _fxsave(&targetFXSAVE); - u32 result; - memcpy(&result, &targetFXSAVE[28], 4); // bytes 28->32 are the MXCSR_Mask. - if (result != 0) - MXCSR_Mask.bitmask = result; + u32 result; + memcpy(&result, &targetFXSAVE[28], 4); // bytes 28->32 are the MXCSR_Mask. + if (result != 0) + MXCSR_Mask.bitmask = result; } // Counts the number of cpu cycles executed over the requested number of PerformanceCounter @@ -103,221 +104,229 @@ void x86capabilities::SIMD_EstablishMXCSRmask() // by the operating system task switches. s64 x86capabilities::_CPUSpeedHz(u64 time) const { - u64 timeStart, timeStop; - s64 startCycle, endCycle; + u64 timeStart, timeStop; + s64 startCycle, endCycle; - if (!hasTimeStampCounter) - return 0; + if (!hasTimeStampCounter) + return 0; - SingleCoreAffinity affinity_lock; + SingleCoreAffinity affinity_lock; - // Align the cpu execution to a cpuTick boundary. + // Align the cpu execution to a cpuTick boundary. - do { - timeStart = GetCPUTicks(); - startCycle = __rdtsc(); - } while (GetCPUTicks() == timeStart); + do + { + timeStart = GetCPUTicks(); + startCycle = __rdtsc(); + } while (GetCPUTicks() == timeStart); - do { - timeStop = GetCPUTicks(); - endCycle = __rdtsc(); - } while ((timeStop - timeStart) < time); + do + { + timeStop = GetCPUTicks(); + endCycle = __rdtsc(); + } while ((timeStop - timeStart) < time); - s64 cycleCount = endCycle - startCycle; - s64 timeCount = timeStop - timeStart; - s64 overrun = timeCount - time; - if (!overrun) - return cycleCount; + s64 cycleCount = endCycle - startCycle; + s64 timeCount = timeStop - timeStart; + s64 overrun = timeCount - time; + if (!overrun) + return cycleCount; - // interference could cause us to overshoot the target time, compensate: + // interference could cause us to overshoot the target time, compensate: - double cyclesPerTick = (double)cycleCount / (double)timeCount; - double newCycleCount = (double)cycleCount - (cyclesPerTick * overrun); + double cyclesPerTick = (double)cycleCount / (double)timeCount; + double newCycleCount = (double)cycleCount - (cyclesPerTick * overrun); - return (s64)newCycleCount; + return (s64)newCycleCount; } wxString x86capabilities::GetTypeName() const { - switch (TypeID) { - case 0: - return L"Standard OEM"; - case 1: - return L"Overdrive"; - case 2: - return L"Dual"; - case 3: - return L"Reserved"; - default: - return L"Unknown"; - } + switch (TypeID) + { + case 0: + return L"Standard OEM"; + case 1: + return L"Overdrive"; + case 2: + return L"Dual"; + case 3: + return L"Reserved"; + default: + return L"Unknown"; + } } void x86capabilities::CountCores() { - Identify(); + Identify(); - s32 regs[4]; - u32 cmds; + s32 regs[4]; + u32 cmds; - cpuid(regs, 0x80000000); - cmds = regs[0]; + cpuid(regs, 0x80000000); + cmds = regs[0]; - // detect multicore for AMD cpu + // detect multicore for AMD cpu - if ((cmds >= 0x80000008) && (VendorID == x86Vendor_AMD)) { - // AMD note: they don't support hyperthreading, but they like to flag this true - // anyway. Let's force-unflag it until we come up with a better solution. - // (note: seems to affect some Phenom II's only? -- Athlon X2's and PhenomI's do - // not seem to do this) --air - hasMultiThreading = 0; - } + if ((cmds >= 0x80000008) && (VendorID == x86Vendor_AMD)) + { + // AMD note: they don't support hyperthreading, but they like to flag this true + // anyway. Let's force-unflag it until we come up with a better solution. + // (note: seems to affect some Phenom II's only? -- Athlon X2's and PhenomI's do + // not seem to do this) --air + hasMultiThreading = 0; + } - // This will assign values into LogicalCores and PhysicalCores - CountLogicalCores(); + // This will assign values into LogicalCores and PhysicalCores + CountLogicalCores(); } -static const char *tbl_x86vendors[] = - { - "GenuineIntel", - "AuthenticAMD", - "Unknown ", +static const char* tbl_x86vendors[] = + { + "GenuineIntel", + "AuthenticAMD", + "Unknown ", }; // Performs all _cpuid-related activity. This fills *most* of the x86caps structure, except for // the cpuSpeed and the mxcsr masks. Those must be completed manually. void x86capabilities::Identify() { - if (isIdentified) - return; - isIdentified = true; + if (isIdentified) + return; + isIdentified = true; - s32 regs[4]; - u32 cmds; + s32 regs[4]; + u32 cmds; - memzero(VendorName); - cpuid(regs, 0); + memzero(VendorName); + cpuid(regs, 0); - cmds = regs[0]; - memcpy(&VendorName[0], ®s[1], 4); - memcpy(&VendorName[4], ®s[3], 4); - memcpy(&VendorName[8], ®s[2], 4); + cmds = regs[0]; + memcpy(&VendorName[0], ®s[1], 4); + memcpy(&VendorName[4], ®s[3], 4); + memcpy(&VendorName[8], ®s[2], 4); - // Determine Vendor Specifics! - // It's really not recommended that we base much (if anything) on CPU vendor names, - // however it's currently necessary in order to gain a (pseudo)reliable count of cores - // and threads used by the CPU (AMD and Intel can't agree on how to make this info available). + // Determine Vendor Specifics! + // It's really not recommended that we base much (if anything) on CPU vendor names, + // however it's currently necessary in order to gain a (pseudo)reliable count of cores + // and threads used by the CPU (AMD and Intel can't agree on how to make this info available). - int vid; - for (vid = 0; vid < x86Vendor_Unknown; ++vid) { - if (memcmp(VendorName, tbl_x86vendors[vid], 12) == 0) - break; - } - VendorID = static_cast(vid); + int vid; + for (vid = 0; vid < x86Vendor_Unknown; ++vid) + { + if (memcmp(VendorName, tbl_x86vendors[vid], 12) == 0) + break; + } + VendorID = static_cast(vid); - if (cmds >= 0x00000001) { - cpuid(regs, 0x00000001); + if (cmds >= 0x00000001) + { + cpuid(regs, 0x00000001); - StepID = regs[0] & 0xf; - Model = (regs[0] >> 4) & 0xf; - FamilyID = (regs[0] >> 8) & 0xf; - TypeID = (regs[0] >> 12) & 0x3; + StepID = regs[0] & 0xf; + Model = (regs[0] >> 4) & 0xf; + FamilyID = (regs[0] >> 8) & 0xf; + TypeID = (regs[0] >> 12) & 0x3; #ifdef __M_X86_64 - //u32 x86_64_8BITBRANDID = regs[1] & 0xff; + //u32 x86_64_8BITBRANDID = regs[1] & 0xff; #endif - Flags = regs[3]; - Flags2 = regs[2]; - } + Flags = regs[3]; + Flags2 = regs[2]; + } - if (cmds >= 0x00000007) { - // Note: ECX must be 0 for AVX2 detection. - cpuidex(regs, 0x00000007, 0); + if (cmds >= 0x00000007) + { + // Note: ECX must be 0 for AVX2 detection. + cpuidex(regs, 0x00000007, 0); - SEFlag = regs[1]; - } + SEFlag = regs[1]; + } - cpuid(regs, 0x80000000); - cmds = regs[0]; - if (cmds >= 0x80000001) { - cpuid(regs, 0x80000001); + cpuid(regs, 0x80000000); + cmds = regs[0]; + if (cmds >= 0x80000001) + { + cpuid(regs, 0x80000001); #ifdef __M_X86_64 - //u32 x86_64_12BITBRANDID = regs[1] & 0xfff; + //u32 x86_64_12BITBRANDID = regs[1] & 0xfff; #endif - EFlags2 = regs[2]; - EFlags = regs[3]; - } + EFlags2 = regs[2]; + EFlags = regs[3]; + } - memzero(FamilyName); - cpuid((int *)FamilyName, 0x80000002); - cpuid((int *)(FamilyName + 16), 0x80000003); - cpuid((int *)(FamilyName + 32), 0x80000004); + memzero(FamilyName); + cpuid((int*)FamilyName, 0x80000002); + cpuid((int*)(FamilyName + 16), 0x80000003); + cpuid((int*)(FamilyName + 32), 0x80000004); - hasFloatingPointUnit = (Flags >> 0) & 1; - hasVirtual8086ModeEnhancements = (Flags >> 1) & 1; - hasDebuggingExtensions = (Flags >> 2) & 1; - hasPageSizeExtensions = (Flags >> 3) & 1; - hasTimeStampCounter = (Flags >> 4) & 1; - hasModelSpecificRegisters = (Flags >> 5) & 1; - hasPhysicalAddressExtension = (Flags >> 6) & 1; - hasMachineCheckArchitecture = (Flags >> 7) & 1; - hasCOMPXCHG8BInstruction = (Flags >> 8) & 1; - hasAdvancedProgrammableInterruptController = (Flags >> 9) & 1; - hasSEPFastSystemCall = (Flags >> 11) & 1; - hasMemoryTypeRangeRegisters = (Flags >> 12) & 1; - hasPTEGlobalFlag = (Flags >> 13) & 1; - hasMachineCheckArchitecture = (Flags >> 14) & 1; - hasConditionalMoveAndCompareInstructions = (Flags >> 15) & 1; - hasFGPageAttributeTable = (Flags >> 16) & 1; - has36bitPageSizeExtension = (Flags >> 17) & 1; - hasProcessorSerialNumber = (Flags >> 18) & 1; - hasCFLUSHInstruction = (Flags >> 19) & 1; - hasDebugStore = (Flags >> 21) & 1; - hasACPIThermalMonitorAndClockControl = (Flags >> 22) & 1; - hasFastStreamingSIMDExtensionsSaveRestore = (Flags >> 24) & 1; - hasStreamingSIMDExtensions = (Flags >> 25) & 1; //sse - hasStreamingSIMD2Extensions = (Flags >> 26) & 1; //sse2 - hasSelfSnoop = (Flags >> 27) & 1; - hasMultiThreading = (Flags >> 28) & 1; - hasThermalMonitor = (Flags >> 29) & 1; - hasIntel64BitArchitecture = (Flags >> 30) & 1; + hasFloatingPointUnit = (Flags >> 0) & 1; + hasVirtual8086ModeEnhancements = (Flags >> 1) & 1; + hasDebuggingExtensions = (Flags >> 2) & 1; + hasPageSizeExtensions = (Flags >> 3) & 1; + hasTimeStampCounter = (Flags >> 4) & 1; + hasModelSpecificRegisters = (Flags >> 5) & 1; + hasPhysicalAddressExtension = (Flags >> 6) & 1; + hasMachineCheckArchitecture = (Flags >> 7) & 1; + hasCOMPXCHG8BInstruction = (Flags >> 8) & 1; + hasAdvancedProgrammableInterruptController = (Flags >> 9) & 1; + hasSEPFastSystemCall = (Flags >> 11) & 1; + hasMemoryTypeRangeRegisters = (Flags >> 12) & 1; + hasPTEGlobalFlag = (Flags >> 13) & 1; + hasMachineCheckArchitecture = (Flags >> 14) & 1; + hasConditionalMoveAndCompareInstructions = (Flags >> 15) & 1; + hasFGPageAttributeTable = (Flags >> 16) & 1; + has36bitPageSizeExtension = (Flags >> 17) & 1; + hasProcessorSerialNumber = (Flags >> 18) & 1; + hasCFLUSHInstruction = (Flags >> 19) & 1; + hasDebugStore = (Flags >> 21) & 1; + hasACPIThermalMonitorAndClockControl = (Flags >> 22) & 1; + hasFastStreamingSIMDExtensionsSaveRestore = (Flags >> 24) & 1; + hasStreamingSIMDExtensions = (Flags >> 25) & 1; //sse + hasStreamingSIMD2Extensions = (Flags >> 26) & 1; //sse2 + hasSelfSnoop = (Flags >> 27) & 1; + hasMultiThreading = (Flags >> 28) & 1; + hasThermalMonitor = (Flags >> 29) & 1; + hasIntel64BitArchitecture = (Flags >> 30) & 1; - // ------------------------------------------------- - // --> SSE3 / SSSE3 / SSE4.1 / SSE 4.2 detection <-- - // ------------------------------------------------- + // ------------------------------------------------- + // --> SSE3 / SSSE3 / SSE4.1 / SSE 4.2 detection <-- + // ------------------------------------------------- - hasStreamingSIMD3Extensions = (Flags2 >> 0) & 1; //sse3 - hasSupplementalStreamingSIMD3Extensions = (Flags2 >> 9) & 1; //ssse3 - hasStreamingSIMD4Extensions = (Flags2 >> 19) & 1; //sse4.1 - hasStreamingSIMD4Extensions2 = (Flags2 >> 20) & 1; //sse4.2 + hasStreamingSIMD3Extensions = (Flags2 >> 0) & 1; //sse3 + hasSupplementalStreamingSIMD3Extensions = (Flags2 >> 9) & 1; //ssse3 + hasStreamingSIMD4Extensions = (Flags2 >> 19) & 1; //sse4.1 + hasStreamingSIMD4Extensions2 = (Flags2 >> 20) & 1; //sse4.2 - if ((Flags2 >> 27) & 1) // OSXSAVE - { - // Note: In theory, we should use xgetbv to check OS support - // but all OSes we officially run under support it - // and its intrinsic requires extra compiler flags - hasAVX = (Flags2 >> 28) & 1; //avx - hasFMA = (Flags2 >> 12) & 1; //fma - hasAVX2 = (SEFlag >> 5) & 1; //avx2 - } + if ((Flags2 >> 27) & 1) // OSXSAVE + { + // Note: In theory, we should use xgetbv to check OS support + // but all OSes we officially run under support it + // and its intrinsic requires extra compiler flags + hasAVX = (Flags2 >> 28) & 1; //avx + hasFMA = (Flags2 >> 12) & 1; //fma + hasAVX2 = (SEFlag >> 5) & 1; //avx2 + } - hasBMI1 = (SEFlag >> 3) & 1; - hasBMI2 = (SEFlag >> 8) & 1; + hasBMI1 = (SEFlag >> 3) & 1; + hasBMI2 = (SEFlag >> 8) & 1; - // Ones only for AMDs: - hasAMD64BitArchitecture = (EFlags >> 29) & 1; //64bit cpu - hasStreamingSIMD4ExtensionsA = (EFlags2 >> 6) & 1; //INSERTQ / EXTRQ / MOVNT + // Ones only for AMDs: + hasAMD64BitArchitecture = (EFlags >> 29) & 1; //64bit cpu + hasStreamingSIMD4ExtensionsA = (EFlags2 >> 6) & 1; //INSERTQ / EXTRQ / MOVNT - isIdentified = true; + isIdentified = true; } u32 x86capabilities::CalculateMHz() const { - InitCPUTicks(); - u64 span = GetTickFrequency(); + InitCPUTicks(); + u64 span = GetTickFrequency(); - if ((span % 1000) < 400) // helps minimize rounding errors - return (u32)(_CPUSpeedHz(span / 1000) / 1000); - else - return (u32)(_CPUSpeedHz(span / 500) / 2000); + if ((span % 1000) < 400) // helps minimize rounding errors + return (u32)(_CPUSpeedHz(span / 1000) / 1000); + else + return (u32)(_CPUSpeedHz(span / 500) / 2000); } diff --git a/common/emitter/cpudetect_internal.h b/common/emitter/cpudetect_internal.h index b880e7bfbe..7359e565bb 100644 --- a/common/emitter/cpudetect_internal.h +++ b/common/emitter/cpudetect_internal.h @@ -28,11 +28,11 @@ class SingleCoreAffinity { protected: #ifdef _WIN32 - HANDLE s_threadId; - DWORD_PTR s_oldmask; + HANDLE s_threadId; + DWORD_PTR s_oldmask; #endif public: - SingleCoreAffinity(); - virtual ~SingleCoreAffinity(); + SingleCoreAffinity(); + virtual ~SingleCoreAffinity(); }; diff --git a/common/emitter/fpu.cpp b/common/emitter/fpu.cpp index 24a0eb947b..9295d49609 100644 --- a/common/emitter/fpu.cpp +++ b/common/emitter/fpu.cpp @@ -21,9 +21,9 @@ /* fld m32 to fpu reg stack */ emitterT void FLD32(u32 from) { - xWrite8(0xD9); - ModRM(0, 0x0, DISP32); - xWrite32(MEMADDR(from, 4)); + xWrite8(0xD9); + ModRM(0, 0x0, DISP32); + xWrite32(MEMADDR(from, 4)); } // fld st(i) @@ -34,9 +34,9 @@ emitterT void FLDL2E() { xWrite16(0xead9); } /* fstp m32 from fpu reg stack */ emitterT void FSTP32(u32 to) { - xWrite8(0xD9); - ModRM(0, 0x3, DISP32); - xWrite32(MEMADDR(to, 4)); + xWrite8(0xD9); + ModRM(0, 0x3, DISP32); + xWrite32(MEMADDR(to, 4)); } // fstp st(i) @@ -52,21 +52,21 @@ emitterT void FSIN(void) { xWrite16(0xfed9); } /* fadd ST(0) to fpu reg stack ST(src) */ emitterT void FADD320toR(x86IntRegType src) { - xWrite8(0xDC); - xWrite8(0xC0 + src); + xWrite8(0xDC); + xWrite8(0xC0 + src); } /* fsub ST(src) to fpu reg stack ST(0) */ emitterT void FSUB32Rto0(x86IntRegType src) { - xWrite8(0xD8); - xWrite8(0xE0 + src); + xWrite8(0xD8); + xWrite8(0xE0 + src); } /* fmul m32 to fpu reg stack */ emitterT void FMUL32(u32 from) { - xWrite8(0xD8); - ModRM(0, 0x1, DISP32); - xWrite32(MEMADDR(from, 4)); + xWrite8(0xD8); + ModRM(0, 0x1, DISP32); + xWrite32(MEMADDR(from, 4)); } diff --git a/common/emitter/groups.cpp b/common/emitter/groups.cpp index 90a627807c..22a2f3bdeb 100644 --- a/common/emitter/groups.cpp +++ b/common/emitter/groups.cpp @@ -34,222 +34,237 @@ namespace x86Emitter { -// ===================================================================================================== -// Group 1 Instructions - ADD, SUB, ADC, etc. -// ===================================================================================================== + // ===================================================================================================== + // Group 1 Instructions - ADD, SUB, ADC, etc. + // ===================================================================================================== -// Note on "[Indirect],Imm" forms : use int as the source operand since it's "reasonably inert" from a -// compiler perspective. (using uint tends to make the compiler try and fail to match signed immediates -// with one of the other overloads). -static void _g1_IndirectImm(G1Type InstType, const xIndirect64orLess &sibdest, int imm) -{ - if (sibdest.Is8BitOp()) { - xOpWrite(sibdest.GetPrefix16(), 0x80, InstType, sibdest); + // Note on "[Indirect],Imm" forms : use int as the source operand since it's "reasonably inert" from a + // compiler perspective. (using uint tends to make the compiler try and fail to match signed immediates + // with one of the other overloads). + static void _g1_IndirectImm(G1Type InstType, const xIndirect64orLess& sibdest, int imm) + { + if (sibdest.Is8BitOp()) + { + xOpWrite(sibdest.GetPrefix16(), 0x80, InstType, sibdest); - xWrite(imm); - } else { - u8 opcode = is_s8(imm) ? 0x83 : 0x81; - xOpWrite(sibdest.GetPrefix16(), opcode, InstType, sibdest, is_s8(imm) ? 1 : sibdest.GetImmSize()); + xWrite(imm); + } + else + { + u8 opcode = is_s8(imm) ? 0x83 : 0x81; + xOpWrite(sibdest.GetPrefix16(), opcode, InstType, sibdest, is_s8(imm) ? 1 : sibdest.GetImmSize()); - if (is_s8(imm)) - xWrite(imm); - else - sibdest.xWriteImm(imm); - } -} + if (is_s8(imm)) + xWrite(imm); + else + sibdest.xWriteImm(imm); + } + } -void _g1_EmitOp(G1Type InstType, const xRegisterInt &to, const xRegisterInt &from) -{ - pxAssert(to.GetOperandSize() == from.GetOperandSize()); + void _g1_EmitOp(G1Type InstType, const xRegisterInt& to, const xRegisterInt& from) + { + pxAssert(to.GetOperandSize() == from.GetOperandSize()); - u8 opcode = (to.Is8BitOp() ? 0 : 1) | (InstType << 3); - xOpWrite(to.GetPrefix16(), opcode, from, to); -} + u8 opcode = (to.Is8BitOp() ? 0 : 1) | (InstType << 3); + xOpWrite(to.GetPrefix16(), opcode, from, to); + } -static void _g1_EmitOp(G1Type InstType, const xIndirectVoid &sibdest, const xRegisterInt &from) -{ - u8 opcode = (from.Is8BitOp() ? 0 : 1) | (InstType << 3); - xOpWrite(from.GetPrefix16(), opcode, from, sibdest); -} + static void _g1_EmitOp(G1Type InstType, const xIndirectVoid& sibdest, const xRegisterInt& from) + { + u8 opcode = (from.Is8BitOp() ? 0 : 1) | (InstType << 3); + xOpWrite(from.GetPrefix16(), opcode, from, sibdest); + } -static void _g1_EmitOp(G1Type InstType, const xRegisterInt &to, const xIndirectVoid &sibsrc) -{ - u8 opcode = (to.Is8BitOp() ? 2 : 3) | (InstType << 3); - xOpWrite(to.GetPrefix16(), opcode, to, sibsrc); -} + static void _g1_EmitOp(G1Type InstType, const xRegisterInt& to, const xIndirectVoid& sibsrc) + { + u8 opcode = (to.Is8BitOp() ? 2 : 3) | (InstType << 3); + xOpWrite(to.GetPrefix16(), opcode, to, sibsrc); + } -static void _g1_EmitOp(G1Type InstType, const xRegisterInt &to, int imm) -{ - if (!to.Is8BitOp() && is_s8(imm)) { - xOpWrite(to.GetPrefix16(), 0x83, InstType, to); - xWrite(imm); - } else { - if (to.IsAccumulator()) { - u8 opcode = (to.Is8BitOp() ? 4 : 5) | (InstType << 3); - xOpAccWrite(to.GetPrefix16(), opcode, InstType, to); - } else { - u8 opcode = to.Is8BitOp() ? 0x80 : 0x81; - xOpWrite(to.GetPrefix16(), opcode, InstType, to); - } - to.xWriteImm(imm); - } -} + static void _g1_EmitOp(G1Type InstType, const xRegisterInt& to, int imm) + { + if (!to.Is8BitOp() && is_s8(imm)) + { + xOpWrite(to.GetPrefix16(), 0x83, InstType, to); + xWrite(imm); + } + else + { + if (to.IsAccumulator()) + { + u8 opcode = (to.Is8BitOp() ? 4 : 5) | (InstType << 3); + xOpAccWrite(to.GetPrefix16(), opcode, InstType, to); + } + else + { + u8 opcode = to.Is8BitOp() ? 0x80 : 0x81; + xOpWrite(to.GetPrefix16(), opcode, InstType, to); + } + to.xWriteImm(imm); + } + } -#define ImplementGroup1(g1type, insttype) \ - void g1type::operator()(const xRegisterInt &to, const xRegisterInt &from) const { _g1_EmitOp(insttype, to, from); } \ - void g1type::operator()(const xIndirectVoid &to, const xRegisterInt &from) const { _g1_EmitOp(insttype, to, from); } \ - void g1type::operator()(const xRegisterInt &to, const xIndirectVoid &from) const { _g1_EmitOp(insttype, to, from); } \ - void g1type::operator()(const xRegisterInt &to, int imm) const { _g1_EmitOp(insttype, to, imm); } \ - void g1type::operator()(const xIndirect64orLess &sibdest, int imm) const { _g1_IndirectImm(insttype, sibdest, imm); } +#define ImplementGroup1(g1type, insttype) \ + void g1type::operator()(const xRegisterInt& to, const xRegisterInt& from) const { _g1_EmitOp(insttype, to, from); } \ + void g1type::operator()(const xIndirectVoid& to, const xRegisterInt& from) const { _g1_EmitOp(insttype, to, from); } \ + void g1type::operator()(const xRegisterInt& to, const xIndirectVoid& from) const { _g1_EmitOp(insttype, to, from); } \ + void g1type::operator()(const xRegisterInt& to, int imm) const { _g1_EmitOp(insttype, to, imm); } \ + void g1type::operator()(const xIndirect64orLess& sibdest, int imm) const { _g1_IndirectImm(insttype, sibdest, imm); } -ImplementGroup1(xImpl_Group1, InstType) - ImplementGroup1(xImpl_G1Logic, InstType) - ImplementGroup1(xImpl_G1Arith, InstType) - ImplementGroup1(xImpl_G1Compare, G1Type_CMP) + ImplementGroup1(xImpl_Group1, InstType) + ImplementGroup1(xImpl_G1Logic, InstType) + ImplementGroup1(xImpl_G1Arith, InstType) + ImplementGroup1(xImpl_G1Compare, G1Type_CMP) - const xImpl_G1Logic xAND = {G1Type_AND, {0x00, 0x54}, {0x66, 0x54}}; -const xImpl_G1Logic xOR = {G1Type_OR, {0x00, 0x56}, {0x66, 0x56}}; -const xImpl_G1Logic xXOR = {G1Type_XOR, {0x00, 0x57}, {0x66, 0x57}}; + const xImpl_G1Logic xAND = {G1Type_AND, {0x00, 0x54}, {0x66, 0x54}}; + const xImpl_G1Logic xOR = {G1Type_OR, {0x00, 0x56}, {0x66, 0x56}}; + const xImpl_G1Logic xXOR = {G1Type_XOR, {0x00, 0x57}, {0x66, 0x57}}; -const xImpl_G1Arith xADD = {G1Type_ADD, {0x00, 0x58}, {0x66, 0x58}, {0xf3, 0x58}, {0xf2, 0x58}}; -const xImpl_G1Arith xSUB = {G1Type_SUB, {0x00, 0x5c}, {0x66, 0x5c}, {0xf3, 0x5c}, {0xf2, 0x5c}}; -const xImpl_G1Compare xCMP = {{0x00, 0xc2}, {0x66, 0xc2}, {0xf3, 0xc2}, {0xf2, 0xc2}}; + const xImpl_G1Arith xADD = {G1Type_ADD, {0x00, 0x58}, {0x66, 0x58}, {0xf3, 0x58}, {0xf2, 0x58}}; + const xImpl_G1Arith xSUB = {G1Type_SUB, {0x00, 0x5c}, {0x66, 0x5c}, {0xf3, 0x5c}, {0xf2, 0x5c}}; + const xImpl_G1Compare xCMP = {{0x00, 0xc2}, {0x66, 0xc2}, {0xf3, 0xc2}, {0xf2, 0xc2}}; -const xImpl_Group1 xADC = {G1Type_ADC}; -const xImpl_Group1 xSBB = {G1Type_SBB}; + const xImpl_Group1 xADC = {G1Type_ADC}; + const xImpl_Group1 xSBB = {G1Type_SBB}; -// ===================================================================================================== -// Group 2 Instructions - SHR, SHL, etc. -// ===================================================================================================== + // ===================================================================================================== + // Group 2 Instructions - SHR, SHL, etc. + // ===================================================================================================== -void xImpl_Group2::operator()(const xRegisterInt &to, const xRegisterCL & /* from */) const -{ - xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xd2 : 0xd3, InstType, to); -} + void xImpl_Group2::operator()(const xRegisterInt& to, const xRegisterCL& /* from */) const + { + xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xd2 : 0xd3, InstType, to); + } -void xImpl_Group2::operator()(const xRegisterInt &to, u8 imm) const -{ - if (imm == 0) - return; + void xImpl_Group2::operator()(const xRegisterInt& to, u8 imm) const + { + if (imm == 0) + return; - if (imm == 1) { - // special encoding of 1's - xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xd0 : 0xd1, InstType, to); - } else { - xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xc0 : 0xc1, InstType, to); - xWrite8(imm); - } -} + if (imm == 1) + { + // special encoding of 1's + xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xd0 : 0xd1, InstType, to); + } + else + { + xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xc0 : 0xc1, InstType, to); + xWrite8(imm); + } + } -void xImpl_Group2::operator()(const xIndirect64orLess &sibdest, const xRegisterCL & /* from */) const -{ - xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xd2 : 0xd3, InstType, sibdest); -} + void xImpl_Group2::operator()(const xIndirect64orLess& sibdest, const xRegisterCL& /* from */) const + { + xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xd2 : 0xd3, InstType, sibdest); + } -void xImpl_Group2::operator()(const xIndirect64orLess &sibdest, u8 imm) const -{ - if (imm == 0) - return; + void xImpl_Group2::operator()(const xIndirect64orLess& sibdest, u8 imm) const + { + if (imm == 0) + return; - if (imm == 1) { - // special encoding of 1's - xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xd0 : 0xd1, InstType, sibdest); - } else { - xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xc0 : 0xc1, InstType, sibdest, 1); - xWrite8(imm); - } -} + if (imm == 1) + { + // special encoding of 1's + xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xd0 : 0xd1, InstType, sibdest); + } + else + { + xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xc0 : 0xc1, InstType, sibdest, 1); + xWrite8(imm); + } + } -const xImpl_Group2 xROL = {G2Type_ROL}; -const xImpl_Group2 xROR = {G2Type_ROR}; -const xImpl_Group2 xRCL = {G2Type_RCL}; -const xImpl_Group2 xRCR = {G2Type_RCR}; -const xImpl_Group2 xSHL = {G2Type_SHL}; -const xImpl_Group2 xSHR = {G2Type_SHR}; -const xImpl_Group2 xSAR = {G2Type_SAR}; + const xImpl_Group2 xROL = {G2Type_ROL}; + const xImpl_Group2 xROR = {G2Type_ROR}; + const xImpl_Group2 xRCL = {G2Type_RCL}; + const xImpl_Group2 xRCR = {G2Type_RCR}; + const xImpl_Group2 xSHL = {G2Type_SHL}; + const xImpl_Group2 xSHR = {G2Type_SHR}; + const xImpl_Group2 xSAR = {G2Type_SAR}; -// ===================================================================================================== -// Group 3 Instructions - NOT, NEG, MUL, DIV -// ===================================================================================================== + // ===================================================================================================== + // Group 3 Instructions - NOT, NEG, MUL, DIV + // ===================================================================================================== -static void _g3_EmitOp(G3Type InstType, const xRegisterInt &from) -{ - xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from); -} + static void _g3_EmitOp(G3Type InstType, const xRegisterInt& from) + { + xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from); + } -static void _g3_EmitOp(G3Type InstType, const xIndirect64orLess &from) -{ - xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from); -} + static void _g3_EmitOp(G3Type InstType, const xIndirect64orLess& from) + { + xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from); + } -void xImpl_Group3::operator()(const xRegisterInt &from) const { _g3_EmitOp(InstType, from); } -void xImpl_Group3::operator()(const xIndirect64orLess &from) const { _g3_EmitOp(InstType, from); } + void xImpl_Group3::operator()(const xRegisterInt& from) const { _g3_EmitOp(InstType, from); } + void xImpl_Group3::operator()(const xIndirect64orLess& from) const { _g3_EmitOp(InstType, from); } -void xImpl_iDiv::operator()(const xRegisterInt &from) const { _g3_EmitOp(G3Type_iDIV, from); } -void xImpl_iDiv::operator()(const xIndirect64orLess &from) const { _g3_EmitOp(G3Type_iDIV, from); } + void xImpl_iDiv::operator()(const xRegisterInt& from) const { _g3_EmitOp(G3Type_iDIV, from); } + void xImpl_iDiv::operator()(const xIndirect64orLess& from) const { _g3_EmitOp(G3Type_iDIV, from); } -template -static void _imul_ImmStyle(const xRegisterInt ¶m1, const SrcType ¶m2, int imm) -{ - pxAssert(param1.GetOperandSize() == param2.GetOperandSize()); + template + static void _imul_ImmStyle(const xRegisterInt& param1, const SrcType& param2, int imm) + { + pxAssert(param1.GetOperandSize() == param2.GetOperandSize()); - xOpWrite0F(param1.GetPrefix16(), is_s8(imm) ? 0x6b : 0x69, param1, param2, is_s8(imm) ? 1 : param1.GetImmSize()); + xOpWrite0F(param1.GetPrefix16(), is_s8(imm) ? 0x6b : 0x69, param1, param2, is_s8(imm) ? 1 : param1.GetImmSize()); - if (is_s8(imm)) - xWrite8((u8)imm); - else - param1.xWriteImm(imm); -} + if (is_s8(imm)) + xWrite8((u8)imm); + else + param1.xWriteImm(imm); + } -void xImpl_iMul::operator()(const xRegisterInt &from) const { _g3_EmitOp(G3Type_iMUL, from); } -void xImpl_iMul::operator()(const xIndirect64orLess &from) const { _g3_EmitOp(G3Type_iMUL, from); } + void xImpl_iMul::operator()(const xRegisterInt& from) const { _g3_EmitOp(G3Type_iMUL, from); } + void xImpl_iMul::operator()(const xIndirect64orLess& from) const { _g3_EmitOp(G3Type_iMUL, from); } -void xImpl_iMul::operator()(const xRegister32 &to, const xRegister32 &from) const { xOpWrite0F(0xaf, to, from); } -void xImpl_iMul::operator()(const xRegister32 &to, const xIndirectVoid &src) const { xOpWrite0F(0xaf, to, src); } -void xImpl_iMul::operator()(const xRegister16 &to, const xRegister16 &from) const { xOpWrite0F(0x66, 0xaf, to, from); } -void xImpl_iMul::operator()(const xRegister16 &to, const xIndirectVoid &src) const { xOpWrite0F(0x66, 0xaf, to, src); } + void xImpl_iMul::operator()(const xRegister32& to, const xRegister32& from) const { xOpWrite0F(0xaf, to, from); } + void xImpl_iMul::operator()(const xRegister32& to, const xIndirectVoid& src) const { xOpWrite0F(0xaf, to, src); } + void xImpl_iMul::operator()(const xRegister16& to, const xRegister16& from) const { xOpWrite0F(0x66, 0xaf, to, from); } + void xImpl_iMul::operator()(const xRegister16& to, const xIndirectVoid& src) const { xOpWrite0F(0x66, 0xaf, to, src); } -void xImpl_iMul::operator()(const xRegister32 &to, const xRegister32 &from, s32 imm) const { _imul_ImmStyle(to, from, imm); } -void xImpl_iMul::operator()(const xRegister32 &to, const xIndirectVoid &from, s32 imm) const { _imul_ImmStyle(to, from, imm); } -void xImpl_iMul::operator()(const xRegister16 &to, const xRegister16 &from, s16 imm) const { _imul_ImmStyle(to, from, imm); } -void xImpl_iMul::operator()(const xRegister16 &to, const xIndirectVoid &from, s16 imm) const { _imul_ImmStyle(to, from, imm); } + void xImpl_iMul::operator()(const xRegister32& to, const xRegister32& from, s32 imm) const { _imul_ImmStyle(to, from, imm); } + void xImpl_iMul::operator()(const xRegister32& to, const xIndirectVoid& from, s32 imm) const { _imul_ImmStyle(to, from, imm); } + void xImpl_iMul::operator()(const xRegister16& to, const xRegister16& from, s16 imm) const { _imul_ImmStyle(to, from, imm); } + void xImpl_iMul::operator()(const xRegister16& to, const xIndirectVoid& from, s16 imm) const { _imul_ImmStyle(to, from, imm); } -const xImpl_Group3 xNOT = {G3Type_NOT}; -const xImpl_Group3 xNEG = {G3Type_NEG}; -const xImpl_Group3 xUMUL = {G3Type_MUL}; -const xImpl_Group3 xUDIV = {G3Type_DIV}; + const xImpl_Group3 xNOT = {G3Type_NOT}; + const xImpl_Group3 xNEG = {G3Type_NEG}; + const xImpl_Group3 xUMUL = {G3Type_MUL}; + const xImpl_Group3 xUDIV = {G3Type_DIV}; -const xImpl_iDiv xDIV = {{0x00, 0x5e}, {0x66, 0x5e}, {0xf3, 0x5e}, {0xf2, 0x5e}}; -const xImpl_iMul xMUL = {{0x00, 0x59}, {0x66, 0x59}, {0xf3, 0x59}, {0xf2, 0x59}}; + const xImpl_iDiv xDIV = {{0x00, 0x5e}, {0x66, 0x5e}, {0xf3, 0x5e}, {0xf2, 0x5e}}; + const xImpl_iMul xMUL = {{0x00, 0x59}, {0x66, 0x59}, {0xf3, 0x59}, {0xf2, 0x59}}; -// ===================================================================================================== -// Group 8 Instructions -// ===================================================================================================== + // ===================================================================================================== + // Group 8 Instructions + // ===================================================================================================== -void xImpl_Group8::operator()(const xRegister16or32or64 &bitbase, const xRegister16or32or64 &bitoffset) const -{ - pxAssert(bitbase->GetOperandSize() == bitoffset->GetOperandSize()); - xOpWrite0F(bitbase->GetPrefix16(), 0xa3 | (InstType << 3), bitbase, bitoffset); -} -void xImpl_Group8::operator()(const xIndirect64 &bitbase, u8 bitoffset) const { xOpWrite0F(0xba, InstType, bitbase, bitoffset); } -void xImpl_Group8::operator()(const xIndirect32 &bitbase, u8 bitoffset) const { xOpWrite0F(0xba, InstType, bitbase, bitoffset); } -void xImpl_Group8::operator()(const xIndirect16 &bitbase, u8 bitoffset) const { xOpWrite0F(0x66, 0xba, InstType, bitbase, bitoffset); } + void xImpl_Group8::operator()(const xRegister16or32or64& bitbase, const xRegister16or32or64& bitoffset) const + { + pxAssert(bitbase->GetOperandSize() == bitoffset->GetOperandSize()); + xOpWrite0F(bitbase->GetPrefix16(), 0xa3 | (InstType << 3), bitbase, bitoffset); + } + void xImpl_Group8::operator()(const xIndirect64& bitbase, u8 bitoffset) const { xOpWrite0F(0xba, InstType, bitbase, bitoffset); } + void xImpl_Group8::operator()(const xIndirect32& bitbase, u8 bitoffset) const { xOpWrite0F(0xba, InstType, bitbase, bitoffset); } + void xImpl_Group8::operator()(const xIndirect16& bitbase, u8 bitoffset) const { xOpWrite0F(0x66, 0xba, InstType, bitbase, bitoffset); } -void xImpl_Group8::operator()(const xRegister16or32or64 &bitbase, u8 bitoffset) const -{ - xOpWrite0F(bitbase->GetPrefix16(), 0xba, InstType, bitbase, bitoffset); -} + void xImpl_Group8::operator()(const xRegister16or32or64& bitbase, u8 bitoffset) const + { + xOpWrite0F(bitbase->GetPrefix16(), 0xba, InstType, bitbase, bitoffset); + } -void xImpl_Group8::operator()(const xIndirectVoid &bitbase, const xRegister16or32or64 &bitoffset) const -{ - xOpWrite0F(bitoffset->GetPrefix16(), 0xa3 | (InstType << 3), bitoffset, bitbase); -} + void xImpl_Group8::operator()(const xIndirectVoid& bitbase, const xRegister16or32or64& bitoffset) const + { + xOpWrite0F(bitoffset->GetPrefix16(), 0xa3 | (InstType << 3), bitoffset, bitbase); + } -const xImpl_Group8 xBT = {G8Type_BT}; -const xImpl_Group8 xBTR = {G8Type_BTR}; -const xImpl_Group8 xBTS = {G8Type_BTS}; -const xImpl_Group8 xBTC = {G8Type_BTC}; + const xImpl_Group8 xBT = {G8Type_BT}; + const xImpl_Group8 xBTR = {G8Type_BTR}; + const xImpl_Group8 xBTS = {G8Type_BTS}; + const xImpl_Group8 xBTC = {G8Type_BTC}; diff --git a/common/emitter/implement/bmi.h b/common/emitter/implement/bmi.h index 6a8e777a6b..9b9f1e10b0 100644 --- a/common/emitter/implement/bmi.h +++ b/common/emitter/implement/bmi.h @@ -20,19 +20,19 @@ 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 @@ -57,5 +57,5 @@ struct xImplBMI_RVM void operator()( const xRegisterInt& to, const xRegisterInt& from, u8 imm) const; void operator()( const xRegisterInt& to, const xIndirectVoid& from, u8 imm) const; #endif -}; -} + }; +} // namespace x86Emitter diff --git a/common/emitter/implement/dwshift.h b/common/emitter/implement/dwshift.h index c2eee26656..9c1b1c84bf 100644 --- a/common/emitter/implement/dwshift.h +++ b/common/emitter/implement/dwshift.h @@ -18,27 +18,27 @@ namespace x86Emitter { -// Implementations here cover SHLD and SHRD. + // Implementations here cover SHLD and SHRD. -// -------------------------------------------------------------------------------------- -// xImpl_DowrdShift -// -------------------------------------------------------------------------------------- -// I use explicit method declarations here instead of templates, in order to provide -// *only* 32 and 16 bit register operand forms (8 bit registers are not valid in SHLD/SHRD). -// -// Optimization Note: Imm shifts by 0 are ignore (no code generated). This is a safe optimization -// because shifts by 0 do *not* affect flags status (intel docs cited). -// -struct xImpl_DwordShift -{ - u16 OpcodeBase; + // -------------------------------------------------------------------------------------- + // xImpl_DowrdShift + // -------------------------------------------------------------------------------------- + // I use explicit method declarations here instead of templates, in order to provide + // *only* 32 and 16 bit register operand forms (8 bit registers are not valid in SHLD/SHRD). + // + // Optimization Note: Imm shifts by 0 are ignore (no code generated). This is a safe optimization + // because shifts by 0 do *not* affect flags status (intel docs cited). + // + struct xImpl_DwordShift + { + 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 diff --git a/common/emitter/implement/group1.h b/common/emitter/implement/group1.h index 1981e133f3..6f421cf2f5 100644 --- a/common/emitter/implement/group1.h +++ b/common/emitter/implement/group1.h @@ -18,32 +18,33 @@ namespace x86Emitter { -enum G1Type { - 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; + // -------------------------------------------------------------------------------------- + // xImpl_Group1 + // -------------------------------------------------------------------------------------- + struct xImpl_Group1 + { + 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 // ------------------------------------------------------------------------ @@ -79,64 +80,64 @@ struct xImpl_Group1 _DoI_helpermess( *this, to, xDirectOrIndirect( from ) ); } #endif -}; + }; -// ------------------------------------------------------------------------ -// This class combines x86 with SSE/SSE2 logic operations (ADD, OR, and NOT). -// Note: ANDN [AndNot] is handled below separately. -// -struct xImpl_G1Logic -{ - G1Type InstType; + // ------------------------------------------------------------------------ + // This class combines x86 with SSE/SSE2 logic operations (ADD, OR, and NOT). + // Note: ANDN [AndNot] is handled below separately. + // + struct xImpl_G1Logic + { + 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 + }; -// ------------------------------------------------------------------------ -// This class combines x86 with SSE/SSE2 arithmetic operations (ADD/SUB). -// -struct xImpl_G1Arith -{ - G1Type InstType; + // ------------------------------------------------------------------------ + // This class combines x86 with SSE/SSE2 arithmetic operations (ADD/SUB). + // + struct xImpl_G1Arith + { + 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; + // ------------------------------------------------------------------------ + struct xImpl_G1Compare + { + 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 diff --git a/common/emitter/implement/group2.h b/common/emitter/implement/group2.h index ae42e12afa..623c33fd3a 100644 --- a/common/emitter/implement/group2.h +++ b/common/emitter/implement/group2.h @@ -18,32 +18,33 @@ namespace x86Emitter { -enum G2Type { - 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 + }; -// -------------------------------------------------------------------------------------- -// xImpl_Group2 -// -------------------------------------------------------------------------------------- -// Group 2 (shift) instructions have no Sib/ModRM forms. -// 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. -// -struct xImpl_Group2 -{ - G2Type InstType; + // -------------------------------------------------------------------------------------- + // xImpl_Group2 + // -------------------------------------------------------------------------------------- + // Group 2 (shift) instructions have no Sib/ModRM forms. + // 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. + // + struct xImpl_Group2 + { + 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 // ------------------------------------------------------------------------ @@ -57,6 +58,6 @@ struct xImpl_Group2 _DoI_helpermess( *this, to, from ); } #endif -}; + }; } // End namespace x86Emitter diff --git a/common/emitter/implement/group3.h b/common/emitter/implement/group3.h index 69eeafed31..e3c7e008a2 100644 --- a/common/emitter/implement/group3.h +++ b/common/emitter/implement/group3.h @@ -18,24 +18,25 @@ namespace x86Emitter { -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 -}; + 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 + }; -// -------------------------------------------------------------------------------------- -// xImpl_Group3 -// -------------------------------------------------------------------------------------- -struct xImpl_Group3 -{ - G3Type InstType; + // -------------------------------------------------------------------------------------- + // xImpl_Group3 + // -------------------------------------------------------------------------------------- + struct xImpl_Group3 + { + 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 > @@ -44,65 +45,65 @@ struct xImpl_Group3 _DoI_helpermess( *this, from ); } #endif -}; + }; -// -------------------------------------------------------------------------------------- -// xImpl_MulDivBase -// -------------------------------------------------------------------------------------- -// This class combines x86 and SSE/SSE2 instructions for iMUL and iDIV. -// -struct xImpl_MulDivBase -{ - G3Type InstType; - u16 OpcodeSSE; + // -------------------------------------------------------------------------------------- + // xImpl_MulDivBase + // -------------------------------------------------------------------------------------- + // This class combines x86 and SSE/SSE2 instructions for iMUL and iDIV. + // + struct xImpl_MulDivBase + { + 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; + }; -// -------------------------------------------------------------------------------------- -// xImpl_iDiv -// -------------------------------------------------------------------------------------- -struct xImpl_iDiv -{ - void operator()(const xRegisterInt &from) const; - void operator()(const xIndirect64orLess &from) const; + // -------------------------------------------------------------------------------------- + // xImpl_iDiv + // -------------------------------------------------------------------------------------- + struct xImpl_iDiv + { + 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; + }; -// -------------------------------------------------------------------------------------- -// xImpl_iMul -// -------------------------------------------------------------------------------------- -// -struct xImpl_iMul -{ - void operator()(const xRegisterInt &from) const; - void operator()(const xIndirect64orLess &from) const; + // -------------------------------------------------------------------------------------- + // xImpl_iMul + // -------------------------------------------------------------------------------------- + // + struct xImpl_iMul + { + 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; + }; +} // namespace x86Emitter diff --git a/common/emitter/implement/incdec.h b/common/emitter/implement/incdec.h index 2a01a2d345..4db3f3d38b 100644 --- a/common/emitter/implement/incdec.h +++ b/common/emitter/implement/incdec.h @@ -21,15 +21,15 @@ namespace x86Emitter { -// -------------------------------------------------------------------------------------- -// xImpl_IncDec -// -------------------------------------------------------------------------------------- -struct xImpl_IncDec -{ - bool isDec; + // -------------------------------------------------------------------------------------- + // xImpl_IncDec + // -------------------------------------------------------------------------------------- + struct xImpl_IncDec + { + 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 diff --git a/common/emitter/implement/jmpcall.h b/common/emitter/implement/jmpcall.h index e07c3142a9..6608eb3d4b 100644 --- a/common/emitter/implement/jmpcall.h +++ b/common/emitter/implement/jmpcall.h @@ -20,74 +20,75 @@ 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; + // ------------------------------------------------------------------------ + struct xImpl_JmpCall + { + bool isJmp; - void operator()(const xAddressReg &absreg) const; - void operator()(const xIndirectNative &src) const; + void operator()(const xAddressReg& absreg) const; + void operator()(const xIndirectNative& 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); - pxAssertMsg(dest == (s32)dest, "Indirect jump is too far, must use a register!"); - xWrite8(0xe8); - xWrite32(dest); - } - } -}; + sptr dest = (sptr)func - ((sptr)xGetPtr() + 5); + pxAssertMsg(dest == (s32)dest, "Indirect jump is too far, must use a register!"); + 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; + // 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; -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. + 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. - void operator()(void *f, const xRegister32 &a1 = xEmptyReg, const xRegister32 &a2 = xEmptyReg) const; + void operator()(void* f, const xRegister32& a1 = xEmptyReg, const xRegister32& a2 = xEmptyReg) const; - void operator()(void *f, u32 a1, const xRegister32 &a2) const; - void operator()(void *f, const xIndirect32 &a1) const; - void operator()(void *f, u32 a1, u32 a2) const; - void operator()(void *f, void *a1) const; + void operator()(void* f, u32 a1, const xRegister32& a2) const; + void operator()(void* f, const xIndirect32& a1) const; + void operator()(void* f, u32 a1, u32 a2) const; + void operator()(void* f, void* a1) const; #ifdef __M_X86_64 - void operator()(void *f, const xRegisterLong &a1, const xRegisterLong &a2 = xEmptyReg) const; - void operator()(void *f, u32 a1, const xRegisterLong &a2) const; + void operator()(void* f, const xRegisterLong& a1, const xRegisterLong& a2 = xEmptyReg) const; + void operator()(void* f, u32 a1, const xRegisterLong& a2) const; #endif - template - __fi void operator()(T *func, u32 a1, const xRegisterLong &a2 = xEmptyReg) const - { - (*this)((void *)func, a1, a2); - } + template + __fi void operator()(T* func, u32 a1, const xRegisterLong& a2 = xEmptyReg) const + { + (*this)((void*)func, a1, a2); + } - template - __fi void operator()(T *func, const xIndirect32 &a1) const - { - (*this)((void*)func, a1); - } + template + __fi void operator()(T* func, const xIndirect32& a1) const + { + (*this)((void*)func, a1); + } - template - __fi void operator()(T *func, u32 a1, u32 a2) const - { - (*this)((void*)func, a1, a2); - } + template + __fi void operator()(T* func, u32 a1, u32 a2) const + { + (*this)((void*)func, a1, a2); + } - void operator()(const xIndirectNative &f, const xRegisterLong &a1 = xEmptyReg, const xRegisterLong &a2 = xEmptyReg) const; -}; + void operator()(const xIndirectNative& f, const xRegisterLong& a1 = xEmptyReg, const xRegisterLong& a2 = xEmptyReg) const; + }; } // End namespace x86Emitter diff --git a/common/emitter/implement/movs.h b/common/emitter/implement/movs.h index 598afca20b..0198f96c53 100644 --- a/common/emitter/implement/movs.h +++ b/common/emitter/implement/movs.h @@ -21,20 +21,20 @@ namespace x86Emitter { -// -------------------------------------------------------------------------------------- -// MovImplAll -// -------------------------------------------------------------------------------------- -// MOV instruction Implementation, plus many SIMD sub-mov variants. -// -struct xImpl_Mov -{ - xImpl_Mov() {} // Satisfy GCC's whims. + // -------------------------------------------------------------------------------------- + // MovImplAll + // -------------------------------------------------------------------------------------- + // MOV instruction Implementation, plus many SIMD sub-mov variants. + // + struct xImpl_Mov + { + 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, sptr imm) const; - void operator()(const xRegisterInt &to, sptr 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, sptr imm) const; + void operator()(const xRegisterInt& to, sptr imm, bool preserve_flags = false) const; #if 0 template< typename T > __noinline void operator()( const ModSibBase& to, const xImmReg& immOrReg ) const @@ -68,73 +68,73 @@ struct xImpl_Mov _DoI_helpermess( *this, to, xDirectOrIndirect( from ) ); }*/ #endif -}; + }; #ifdef __M_X86_64 -// -------------------------------------------------------------------------------------- -// xImpl_MovImm64 -// -------------------------------------------------------------------------------------- -// Mov with 64-bit immediates (only available on 64-bit platforms) -// -struct xImpl_MovImm64 -{ - xImpl_MovImm64() {} // Satisfy GCC's whims. + // -------------------------------------------------------------------------------------- + // xImpl_MovImm64 + // -------------------------------------------------------------------------------------- + // Mov with 64-bit immediates (only available on 64-bit platforms) + // + struct xImpl_MovImm64 + { + xImpl_MovImm64() {} // Satisfy GCC's whims. - void operator()(const xRegister64 &to, s64 imm, bool preserve_flags = false) const; -}; + void operator()(const xRegister64& to, s64 imm, bool preserve_flags = false) const; + }; #endif -// -------------------------------------------------------------------------------------- -// xImpl_CMov -// -------------------------------------------------------------------------------------- -// CMOVcc !! [in all of it's disappointing lack-of glory] .. and .. -// SETcc !! [more glory, less lack!] -// -// CMOV Disclaimer: Caution! This instruction can look exciting and cool, until you -// realize that it cannot load immediate values into registers. -_- -// -// I use explicit method declarations here instead of templates, in order to provide -// *only* 32 and 16 bit register operand forms (8 bit registers are not valid in CMOV). -// + // -------------------------------------------------------------------------------------- + // xImpl_CMov + // -------------------------------------------------------------------------------------- + // CMOVcc !! [in all of it's disappointing lack-of glory] .. and .. + // SETcc !! [more glory, less lack!] + // + // CMOV Disclaimer: Caution! This instruction can look exciting and cool, until you + // realize that it cannot load immediate values into registers. -_- + // + // I use explicit method declarations here instead of templates, in order to provide + // *only* 32 and 16 bit register operand forms (8 bit registers are not valid in CMOV). + // -struct xImpl_CMov -{ - JccComparisonType ccType; - void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from) const; - void operator()(const xRegister16or32or64 &to, const xIndirectVoid &sibsrc) const; + struct xImpl_CMov + { + 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; + struct xImpl_Set + { + 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; + }; -// -------------------------------------------------------------------------------------- -// xImpl_MovExtend -// -------------------------------------------------------------------------------------- -// Mov with sign/zero extension implementations (movsx / movzx) -// -struct xImpl_MovExtend -{ - bool SignExtend; + // -------------------------------------------------------------------------------------- + // xImpl_MovExtend + // -------------------------------------------------------------------------------------- + // Mov with sign/zero extension implementations (movsx / movzx) + // + struct xImpl_MovExtend + { + 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 diff --git a/common/emitter/implement/simd_arithmetic.h b/common/emitter/implement/simd_arithmetic.h index 6de68d1f20..8e8d032736 100644 --- a/common/emitter/implement/simd_arithmetic.h +++ b/common/emitter/implement/simd_arithmetic.h @@ -18,299 +18,299 @@ namespace x86Emitter { -// -------------------------------------------------------------------------------------- -// _SimdShiftHelper -// -------------------------------------------------------------------------------------- -struct _SimdShiftHelper -{ - u8 Prefix; - u16 Opcode; - u16 OpcodeImm; - u8 Modcode; + // -------------------------------------------------------------------------------------- + // _SimdShiftHelper + // -------------------------------------------------------------------------------------- + struct _SimdShiftHelper + { + 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; + }; -// -------------------------------------------------------------------------------------- -// xImplSimd_Shift / xImplSimd_ShiftWithoutQ -// -------------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------------- + // xImplSimd_Shift / xImplSimd_ShiftWithoutQ + // -------------------------------------------------------------------------------------- -// Used for PSRA, which lacks the Q form. -// -struct xImplSimd_ShiftWithoutQ -{ - const _SimdShiftHelper W; - const _SimdShiftHelper D; -}; + // Used for PSRA, which lacks the Q form. + // + struct xImplSimd_ShiftWithoutQ + { + const _SimdShiftHelper W; + const _SimdShiftHelper D; + }; -// Implements PSRL and PSLL -// -struct xImplSimd_Shift -{ - const _SimdShiftHelper W; - const _SimdShiftHelper D; - const _SimdShiftHelper Q; + // Implements PSRL and PSLL + // + struct xImplSimd_Shift + { + 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; + ////////////////////////////////////////////////////////////////////////////////////////// + // + struct xImplSimd_AddSub + { + 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; + ////////////////////////////////////////////////////////////////////////////////////////// + // + struct xImplSimd_PMul + { + 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; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// For instructions that have PS/SS form only (most commonly reciprocal Sqrt functions) -// -struct xImplSimd_rSqrt -{ - const xImplSimd_DestRegSSE PS; - const xImplSimd_DestRegSSE SS; -}; + ////////////////////////////////////////////////////////////////////////////////////////// + // For instructions that have PS/SS form only (most commonly reciprocal Sqrt functions) + // + struct xImplSimd_rSqrt + { + const xImplSimd_DestRegSSE PS; + const xImplSimd_DestRegSSE SS; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// SQRT has PS/SS/SD forms, but not the PD form. -// -struct xImplSimd_Sqrt -{ - const xImplSimd_DestRegSSE PS; - const xImplSimd_DestRegSSE SS; - const xImplSimd_DestRegSSE SD; -}; + ////////////////////////////////////////////////////////////////////////////////////////// + // SQRT has PS/SS/SD forms, but not the PD form. + // + struct xImplSimd_Sqrt + { + const xImplSimd_DestRegSSE PS; + const xImplSimd_DestRegSSE SS; + const xImplSimd_DestRegSSE SD; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// -struct xImplSimd_AndNot -{ - const xImplSimd_DestRegSSE PS; - const xImplSimd_DestRegSSE PD; -}; + ////////////////////////////////////////////////////////////////////////////////////////// + // + struct xImplSimd_AndNot + { + const xImplSimd_DestRegSSE PS; + const xImplSimd_DestRegSSE PD; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// Packed absolute value. [sSSE3 only] -// -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; + ////////////////////////////////////////////////////////////////////////////////////////// + // Packed absolute value. [sSSE3 only] + // + 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 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; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// Packed Sign [sSSE3 only] - Negate/zero/preserve packed integers in dest depending on the -// corresponding sign in src. -// -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; + ////////////////////////////////////////////////////////////////////////////////////////// + // Packed Sign [sSSE3 only] - Negate/zero/preserve packed integers in dest depending on the + // corresponding sign in src. + // + 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 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 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 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; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// Packed Multiply and Add!! -// -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; + ////////////////////////////////////////////////////////////////////////////////////////// + // Packed Multiply and Add!! + // + 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; - // [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; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// Packed Horizontal Add [SSE3 only] -// -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; + ////////////////////////////////////////////////////////////////////////////////////////// + // Packed Horizontal Add [SSE3 only] + // + 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 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; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// DotProduct calculation (SSE4.1 only!) -// -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; + ////////////////////////////////////////////////////////////////////////////////////////// + // DotProduct calculation (SSE4.1 only!) + // + 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] - xImplSimd_DestRegImmSSE PD; -}; + // [SSE-4.1] + xImplSimd_DestRegImmSSE PD; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// Rounds floating point values (packed or single scalar) by an arbitrary rounding mode. -// (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; + ////////////////////////////////////////////////////////////////////////////////////////// + // Rounds floating point values (packed or single scalar) by an arbitrary rounding mode. + // (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 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 diff --git a/common/emitter/implement/simd_comparisons.h b/common/emitter/implement/simd_comparisons.h index 6bf815f9b1..6b06040869 100644 --- a/common/emitter/implement/simd_comparisons.h +++ b/common/emitter/implement/simd_comparisons.h @@ -18,106 +18,106 @@ 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 -}; + 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 + }; -////////////////////////////////////////////////////////////////////////////////////////// -// -struct xImplSimd_Compare -{ - SSE2_ComparisonType CType; + ////////////////////////////////////////////////////////////////////////////////////////// + // + struct xImplSimd_Compare + { + 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; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// Compare scalar floating point values and set EFLAGS (Ordered or Unordered) -// -struct xImplSimd_COMI -{ - const xImplSimd_DestRegSSE SS; - const xImplSimd_DestRegSSE SD; -}; + ////////////////////////////////////////////////////////////////////////////////////////// + // Compare scalar floating point values and set EFLAGS (Ordered or Unordered) + // + struct xImplSimd_COMI + { + const xImplSimd_DestRegSSE SS; + const xImplSimd_DestRegSSE SD; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// -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; + ////////////////////////////////////////////////////////////////////////////////////////// + // + 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 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; + ////////////////////////////////////////////////////////////////////////////////////////// + // + 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 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 diff --git a/common/emitter/implement/simd_helpers.h b/common/emitter/implement/simd_helpers.h index 43719f2366..0f7f6461ac 100644 --- a/common/emitter/implement/simd_helpers.h +++ b/common/emitter/implement/simd_helpers.h @@ -18,56 +18,56 @@ namespace x86Emitter { -// ===================================================================================================== -// xImpl_SIMD Types (template free!) -// ===================================================================================================== + // ===================================================================================================== + // xImpl_SIMD Types (template free!) + // ===================================================================================================== -// ------------------------------------------------------------------------ -// For implementing SSE-only logic operations that have xmmreg,xmmreg/rm forms only, -// like ANDPS/ANDPD -// -struct xImplSimd_DestRegSSE -{ - u8 Prefix; - u16 Opcode; + // ------------------------------------------------------------------------ + // For implementing SSE-only logic operations that have xmmreg,xmmreg/rm forms only, + // like ANDPS/ANDPD + // + struct xImplSimd_DestRegSSE + { + 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; + }; -// ------------------------------------------------------------------------ -// For implementing SSE-only logic operations that have xmmreg,reg/rm,imm forms only -// (PSHUFD / PSHUFHW / etc). -// -struct xImplSimd_DestRegImmSSE -{ - u8 Prefix; - u16 Opcode; + // ------------------------------------------------------------------------ + // For implementing SSE-only logic operations that have xmmreg,reg/rm,imm forms only + // (PSHUFD / PSHUFHW / etc). + // + struct xImplSimd_DestRegImmSSE + { + 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; + struct xImplSimd_DestSSE_CmpImm + { + 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; + }; -// ------------------------------------------------------------------------ -// For implementing SSE operations that have reg,reg/rm forms only, -// but accept either MM or XMM destinations (most PADD/PSUB and other P arithmetic ops). -// -struct xImplSimd_DestRegEither -{ - u8 Prefix; - u16 Opcode; + // ------------------------------------------------------------------------ + // For implementing SSE operations that have reg,reg/rm forms only, + // but accept either MM or XMM destinations (most PADD/PSUB and other P arithmetic ops). + // + struct xImplSimd_DestRegEither + { + 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 diff --git a/common/emitter/implement/simd_moremovs.h b/common/emitter/implement/simd_moremovs.h index 72798a15e0..bc80824c21 100644 --- a/common/emitter/implement/simd_moremovs.h +++ b/common/emitter/implement/simd_moremovs.h @@ -18,156 +18,156 @@ namespace x86Emitter { -// -------------------------------------------------------------------------------------- -// xImplSimd_MovHL -// -------------------------------------------------------------------------------------- -// Moves to/from high/low portions of an xmm register. -// These instructions cannot be used in reg/reg form. -// -struct xImplSimd_MovHL -{ - u16 Opcode; + // -------------------------------------------------------------------------------------- + // xImplSimd_MovHL + // -------------------------------------------------------------------------------------- + // Moves to/from high/low portions of an xmm register. + // These instructions cannot be used in reg/reg form. + // + struct xImplSimd_MovHL + { + 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; + }; -// -------------------------------------------------------------------------------------- -// xImplSimd_MovHL_RtoR -// -------------------------------------------------------------------------------------- -// RegtoReg forms of MOVHL/MOVLH -- these are the same opcodes as MOVH/MOVL but -// do something kinda different! Fun! -// -struct xImplSimd_MovHL_RtoR -{ - u16 Opcode; + // -------------------------------------------------------------------------------------- + // xImplSimd_MovHL_RtoR + // -------------------------------------------------------------------------------------- + // RegtoReg forms of MOVHL/MOVLH -- these are the same opcodes as MOVH/MOVL but + // do something kinda different! Fun! + // + struct xImplSimd_MovHL_RtoR + { + 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; + }; -// -------------------------------------------------------------------------------------- -// xImplSimd_MoveSSE -// -------------------------------------------------------------------------------------- -// Legends in their own right: MOVAPS / MOVAPD / MOVUPS / MOVUPD -// -// All implementations of Unaligned Movs will, when possible, use aligned movs instead. -// This happens when using Mem,Reg or Reg,Mem forms where the address is simple displacement -// which can be checked for alignment at runtime. -// -struct xImplSimd_MoveSSE -{ - u8 Prefix; - bool isAligned; + // -------------------------------------------------------------------------------------- + // xImplSimd_MoveSSE + // -------------------------------------------------------------------------------------- + // Legends in their own right: MOVAPS / MOVAPD / MOVUPS / MOVUPD + // + // All implementations of Unaligned Movs will, when possible, use aligned movs instead. + // This happens when using Mem,Reg or Reg,Mem forms where the address is simple displacement + // which can be checked for alignment at runtime. + // + struct xImplSimd_MoveSSE + { + 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; + }; -// -------------------------------------------------------------------------------------- -// xImplSimd_MoveDQ -// -------------------------------------------------------------------------------------- -// Implementations for MOVDQA / MOVDQU -// -// All implementations of Unaligned Movs will, when possible, use aligned movs instead. -// This happens when using Mem,Reg or Reg,Mem forms where the address is simple displacement -// which can be checked for alignment at runtime. + // -------------------------------------------------------------------------------------- + // xImplSimd_MoveDQ + // -------------------------------------------------------------------------------------- + // Implementations for MOVDQA / MOVDQU + // + // All implementations of Unaligned Movs will, when possible, use aligned movs instead. + // This happens when using Mem,Reg or Reg,Mem forms where the address is simple displacement + // which can be checked for alignment at runtime. -struct xImplSimd_MoveDQ -{ - u8 Prefix; - bool isAligned; + struct xImplSimd_MoveDQ + { + 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; + }; -// -------------------------------------------------------------------------------------- -// xImplSimd_Blend -// -------------------------------------------------------------------------------------- -// Blend - Conditional copying of values in src into dest. -// -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; + // -------------------------------------------------------------------------------------- + // xImplSimd_Blend + // -------------------------------------------------------------------------------------- + // Blend - Conditional copying of values in src into dest. + // + 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 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; + }; -// -------------------------------------------------------------------------------------- -// xImplSimd_PMove -// -------------------------------------------------------------------------------------- -// Packed Move with Sign or Zero extension. -// -struct xImplSimd_PMove -{ - u16 OpcodeBase; + // -------------------------------------------------------------------------------------- + // xImplSimd_PMove + // -------------------------------------------------------------------------------------- + // Packed Move with Sign or Zero extension. + // + struct xImplSimd_PMove + { + 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; + }; +} // namespace x86Emitter diff --git a/common/emitter/implement/simd_shufflepack.h b/common/emitter/implement/simd_shufflepack.h index 5d5f0634f1..070087af2d 100644 --- a/common/emitter/implement/simd_shufflepack.h +++ b/common/emitter/implement/simd_shufflepack.h @@ -18,50 +18,50 @@ namespace x86Emitter { -// -------------------------------------------------------------------------------------- -// xImplSimd_Shuffle -// -------------------------------------------------------------------------------------- -struct xImplSimd_Shuffle -{ - inline void _selector_assertion_check(u8 selector) const; + // -------------------------------------------------------------------------------------- + // xImplSimd_Shuffle + // -------------------------------------------------------------------------------------- + struct xImplSimd_Shuffle + { + 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; + }; -// -------------------------------------------------------------------------------------- -// xImplSimd_PShuffle -// -------------------------------------------------------------------------------------- -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; + // -------------------------------------------------------------------------------------- + // xImplSimd_PShuffle + // -------------------------------------------------------------------------------------- + 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 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 // Copies words from src and inserts them into dest at word locations selected with @@ -94,148 +94,148 @@ 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 -}; + }; -// -------------------------------------------------------------------------------------- -// SimdImpl_PUnpack -// -------------------------------------------------------------------------------------- -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; + // -------------------------------------------------------------------------------------- + // SimdImpl_PUnpack + // -------------------------------------------------------------------------------------- + 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 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; + }; -// -------------------------------------------------------------------------------------- -// SimdImpl_Pack -// -------------------------------------------------------------------------------------- -// Pack with Signed or Unsigned Saturation -// -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; + // -------------------------------------------------------------------------------------- + // SimdImpl_Pack + // -------------------------------------------------------------------------------------- + // Pack with Signed or Unsigned Saturation + // + 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 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; + }; -// -------------------------------------------------------------------------------------- -// SimdImpl_Unpack -// -------------------------------------------------------------------------------------- -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; + // -------------------------------------------------------------------------------------- + // SimdImpl_Unpack + // -------------------------------------------------------------------------------------- + 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 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; + struct xImplSimd_InsertExtractHelper + { + 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; + }; -// -------------------------------------------------------------------------------------- -// SimdImpl_PInsert -// -------------------------------------------------------------------------------------- -// PINSRW/B/D [all but Word form are SSE4.1 only!] -// -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; + // -------------------------------------------------------------------------------------- + // SimdImpl_PInsert + // -------------------------------------------------------------------------------------- + // PINSRW/B/D [all but Word form are SSE4.1 only!] + // + 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; - // [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; + }; -////////////////////////////////////////////////////////////////////////////////////////// -// PEXTRW/B/D [all but Word form are SSE4.1 only!] -// -// Note: Word form's indirect memory form is only available in SSE4.1. -// -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; + ////////////////////////////////////////////////////////////////////////////////////////// + // PEXTRW/B/D [all but Word form are SSE4.1 only!] + // + // Note: Word form's indirect memory form is only available in SSE4.1. + // + 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; - // [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; + }; +} // namespace x86Emitter diff --git a/common/emitter/implement/simd_templated_helpers.h b/common/emitter/implement/simd_templated_helpers.h index d7dcf6cfe4..887b4fccf9 100644 --- a/common/emitter/implement/simd_templated_helpers.h +++ b/common/emitter/implement/simd_templated_helpers.h @@ -26,13 +26,13 @@ template 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? }; diff --git a/common/emitter/implement/test.h b/common/emitter/implement/test.h index 4d14ff1eda..d49e1cad1b 100644 --- a/common/emitter/implement/test.h +++ b/common/emitter/implement/test.h @@ -20,55 +20,56 @@ namespace x86Emitter { -// -------------------------------------------------------------------------------------- -// xImpl_Test -// -------------------------------------------------------------------------------------- -// -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; -}; + // -------------------------------------------------------------------------------------- + // xImpl_Test + // -------------------------------------------------------------------------------------- + // + 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; + }; -enum G8Type { - G8Type_BT = 4, - G8Type_BTS, - G8Type_BTR, - G8Type_BTC, -}; + enum G8Type + { + G8Type_BT = 4, + G8Type_BTS, + G8Type_BTR, + G8Type_BTC, + }; -// -------------------------------------------------------------------------------------- -// BSF / BSR -// -------------------------------------------------------------------------------------- -// 16/32 operands are available. No 8 bit ones, not that any of you cared, I bet. -// -struct xImpl_BitScan -{ - // 0xbc [fwd] / 0xbd [rev] - u16 Opcode; + // -------------------------------------------------------------------------------------- + // BSF / BSR + // -------------------------------------------------------------------------------------- + // 16/32 operands are available. No 8 bit ones, not that any of you cared, I bet. + // + struct xImpl_BitScan + { + // 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; + }; -// -------------------------------------------------------------------------------------- -// xImpl_Group8 -// -------------------------------------------------------------------------------------- -// Bit Test Instructions - Valid on 16/32 bit instructions only. -// -struct xImpl_Group8 -{ - G8Type InstType; + // -------------------------------------------------------------------------------------- + // xImpl_Group8 + // -------------------------------------------------------------------------------------- + // Bit Test Instructions - Valid on 16/32 bit instructions only. + // + struct xImpl_Group8 + { + 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 diff --git a/common/emitter/instructions.h b/common/emitter/instructions.h index 012ed7a369..28196ed813 100644 --- a/common/emitter/instructions.h +++ b/common/emitter/instructions.h @@ -32,571 +32,572 @@ 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_Mov xMOV; #ifdef __M_X86_64 -extern const xImpl_MovImm64 xMOV64; + extern const xImpl_MovImm64 xMOV64; #endif -extern const xImpl_Test xTEST; + 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 xCALL; -extern const xImpl_FastCall xFastCall; + extern const xImpl_JmpCall xJMP; + extern const xImpl_JmpCall xCALL; + extern const xImpl_FastCall xFastCall; -// ------------------------------------------------------------------------ -extern const xImpl_CMov xCMOVA, xCMOVAE, - xCMOVB, xCMOVBE, - xCMOVG, xCMOVGE, - xCMOVL, xCMOVLE, + // ------------------------------------------------------------------------ + 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); -/// LEA with a target that will be decided later, guarantees that no optimizations are performed that could change what needs to be written in -extern u32* xLEA_Writeback(xAddressReg to); - -// ----- 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(); -}; - -////////////////////////////////////////////////////////////////////////////////////////// -/// Helper object to save some temporary registers before the call -class xScopedSavedRegisters -{ - std::vector> regs; -public: - xScopedSavedRegisters(std::initializer_list> regs); - ~xScopedSavedRegisters(); -}; - -////////////////////////////////////////////////////////////////////////////////////////// -/// Helper function to calculate base+offset taking into account the limitations of x86-64's RIP-relative addressing -/// (Will either return `base+offset` or LEA `base` into `tmpRegister` and return `tmpRegister+offset`) -xAddressVoid xComplexAddress(const xAddressReg& tmpRegister, void *base, const xAddressVoid& offset); - -////////////////////////////////////////////////////////////////////////////////////////// -/// Helper function to load addresses that may be far from the current instruction pointer -/// On i386, resolves to `mov dst, (sptr)addr` -/// On x86-64, resolves to either `mov dst, (sptr)addr` or `lea dst, [addr]` depending on the distance from RIP -void xLoadFarAddr(const xAddressReg& dst, void *addr); - -////////////////////////////////////////////////////////////////////////////////////////// -// 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 -__fi void xJE(T *func) -{ - xJcc(Jcc_Equal, (void *)(uptr)func); -} -template -__fi void xJZ(T *func) -{ - xJcc(Jcc_Zero, (void *)(uptr)func); -} -template -__fi void xJNE(T *func) -{ - xJcc(Jcc_NotEqual, (void *)(uptr)func); -} -template -__fi void xJNZ(T *func) -{ - xJcc(Jcc_NotZero, (void *)(uptr)func); -} - -template -__fi void xJO(T *func) -{ - xJcc(Jcc_Overflow, (void *)(uptr)func); -} -template -__fi void xJNO(T *func) -{ - xJcc(Jcc_NotOverflow, (void *)(uptr)func); -} -template -__fi void xJC(T *func) -{ - xJcc(Jcc_Carry, (void *)(uptr)func); -} -template -__fi void xJNC(T *func) -{ - xJcc(Jcc_NotCarry, (void *)(uptr)func); -} -template -__fi void xJS(T *func) -{ - xJcc(Jcc_Signed, (void *)(uptr)func); -} -template -__fi void xJNS(T *func) -{ - xJcc(Jcc_Unsigned, (void *)(uptr)func); -} - -template -__fi void xJPE(T *func) -{ - xJcc(Jcc_ParityEven, (void *)(uptr)func); -} -template -__fi void xJPO(T *func) -{ - xJcc(Jcc_ParityOdd, (void *)(uptr)func); -} - -template -__fi void xJL(T *func) -{ - xJcc(Jcc_Less, (void *)(uptr)func); -} -template -__fi void xJLE(T *func) -{ - xJcc(Jcc_LessOrEqual, (void *)(uptr)func); -} -template -__fi void xJG(T *func) -{ - xJcc(Jcc_Greater, (void *)(uptr)func); -} -template -__fi void xJGE(T *func) -{ - xJcc(Jcc_GreaterOrEqual, (void *)(uptr)func); -} - -template -__fi void xJB(T *func) -{ - xJcc(Jcc_Below, (void *)(uptr)func); -} -template -__fi void xJBE(T *func) -{ - xJcc(Jcc_BelowOrEqual, (void *)(uptr)func); -} -template -__fi void xJA(T *func) -{ - xJcc(Jcc_Above, (void *)(uptr)func); -} -template -__fi void xJAE(T *func) -{ - xJcc(Jcc_AboveOrEqual, (void *)(uptr)func); -} - -// ------------------------------------------------------------------------ -// Forward Jump Helpers (act as labels!) - -#define DEFINE_FORWARD_JUMP(label, cond) \ - template \ - class xForward##label : public xForwardJump \ - { \ - public: \ - xForward##label() \ - : xForwardJump(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 xForwardJump8; -typedef xForwardJump 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 xForwardJA8; -typedef xForwardJA xForwardJA32; -typedef xForwardJB xForwardJB8; -typedef xForwardJB xForwardJB32; -typedef xForwardJAE xForwardJAE8; -typedef xForwardJAE xForwardJAE32; -typedef xForwardJBE xForwardJBE8; -typedef xForwardJBE 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 xForwardJG8; -typedef xForwardJG xForwardJG32; -typedef xForwardJL xForwardJL8; -typedef xForwardJL xForwardJL32; -typedef xForwardJGE xForwardJGE8; -typedef xForwardJGE xForwardJGE32; -typedef xForwardJLE xForwardJLE8; -typedef xForwardJLE 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 xForwardJZ8; -typedef xForwardJZ xForwardJZ32; -typedef xForwardJE xForwardJE8; -typedef xForwardJE xForwardJE32; -typedef xForwardJNZ xForwardJNZ8; -typedef xForwardJNZ xForwardJNZ32; -typedef xForwardJNE xForwardJNE8; -typedef xForwardJNE xForwardJNE32; - -DEFINE_FORWARD_JUMP(JS, Jcc_Signed); -DEFINE_FORWARD_JUMP(JNS, Jcc_Unsigned); - -typedef xForwardJS xForwardJS8; -typedef xForwardJS xForwardJS32; -typedef xForwardJNS xForwardJNS8; -typedef xForwardJNS xForwardJNS32; - -DEFINE_FORWARD_JUMP(JO, Jcc_Overflow); -DEFINE_FORWARD_JUMP(JNO, Jcc_NotOverflow); - -typedef xForwardJO xForwardJO8; -typedef xForwardJO xForwardJO32; -typedef xForwardJNO xForwardJNO8; -typedef xForwardJNO xForwardJNO32; - -DEFINE_FORWARD_JUMP(JC, Jcc_Carry); -DEFINE_FORWARD_JUMP(JNC, Jcc_NotCarry); - -typedef xForwardJC xForwardJC8; -typedef xForwardJC xForwardJC32; -typedef xForwardJNC xForwardJNC8; -typedef xForwardJNC xForwardJNC32; - -DEFINE_FORWARD_JUMP(JPE, Jcc_ParityEven); -DEFINE_FORWARD_JUMP(JPO, Jcc_ParityOdd); - -typedef xForwardJPE xForwardJPE8; -typedef xForwardJPE xForwardJPE32; -typedef xForwardJPO xForwardJPO8; -typedef xForwardJPO 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 xRegister32 &to, const xRegisterSSE &from); -extern void xMOVMSKPD(const xRegister32 &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); + xCMOVZ, xCMOVE, + xCMOVNZ, xCMOVNE, + xCMOVO, xCMOVNO, + xCMOVC, xCMOVNC, -// ------------------------------------------------------------------------ - -extern const xImplSimd_MoveSSE xMOVAPS; -extern const xImplSimd_MoveSSE xMOVUPS; -extern const xImplSimd_MoveSSE xMOVAPD; -extern const xImplSimd_MoveSSE xMOVUPD; + 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); + /// LEA with a target that will be decided later, guarantees that no optimizations are performed that could change what needs to be written in + extern u32* xLEA_Writeback(xAddressReg to); + + // ----- 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(); + }; + + ////////////////////////////////////////////////////////////////////////////////////////// + /// Helper object to save some temporary registers before the call + class xScopedSavedRegisters + { + std::vector> regs; + + public: + xScopedSavedRegisters(std::initializer_list> regs); + ~xScopedSavedRegisters(); + }; + + ////////////////////////////////////////////////////////////////////////////////////////// + /// Helper function to calculate base+offset taking into account the limitations of x86-64's RIP-relative addressing + /// (Will either return `base+offset` or LEA `base` into `tmpRegister` and return `tmpRegister+offset`) + xAddressVoid xComplexAddress(const xAddressReg& tmpRegister, void* base, const xAddressVoid& offset); + + ////////////////////////////////////////////////////////////////////////////////////////// + /// Helper function to load addresses that may be far from the current instruction pointer + /// On i386, resolves to `mov dst, (sptr)addr` + /// On x86-64, resolves to either `mov dst, (sptr)addr` or `lea dst, [addr]` depending on the distance from RIP + void xLoadFarAddr(const xAddressReg& dst, void* addr); + + ////////////////////////////////////////////////////////////////////////////////////////// + // 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 + __fi void xJE(T* func) + { + xJcc(Jcc_Equal, (void*)(uptr)func); + } + template + __fi void xJZ(T* func) + { + xJcc(Jcc_Zero, (void*)(uptr)func); + } + template + __fi void xJNE(T* func) + { + xJcc(Jcc_NotEqual, (void*)(uptr)func); + } + template + __fi void xJNZ(T* func) + { + xJcc(Jcc_NotZero, (void*)(uptr)func); + } + + template + __fi void xJO(T* func) + { + xJcc(Jcc_Overflow, (void*)(uptr)func); + } + template + __fi void xJNO(T* func) + { + xJcc(Jcc_NotOverflow, (void*)(uptr)func); + } + template + __fi void xJC(T* func) + { + xJcc(Jcc_Carry, (void*)(uptr)func); + } + template + __fi void xJNC(T* func) + { + xJcc(Jcc_NotCarry, (void*)(uptr)func); + } + template + __fi void xJS(T* func) + { + xJcc(Jcc_Signed, (void*)(uptr)func); + } + template + __fi void xJNS(T* func) + { + xJcc(Jcc_Unsigned, (void*)(uptr)func); + } + + template + __fi void xJPE(T* func) + { + xJcc(Jcc_ParityEven, (void*)(uptr)func); + } + template + __fi void xJPO(T* func) + { + xJcc(Jcc_ParityOdd, (void*)(uptr)func); + } + + template + __fi void xJL(T* func) + { + xJcc(Jcc_Less, (void*)(uptr)func); + } + template + __fi void xJLE(T* func) + { + xJcc(Jcc_LessOrEqual, (void*)(uptr)func); + } + template + __fi void xJG(T* func) + { + xJcc(Jcc_Greater, (void*)(uptr)func); + } + template + __fi void xJGE(T* func) + { + xJcc(Jcc_GreaterOrEqual, (void*)(uptr)func); + } + + template + __fi void xJB(T* func) + { + xJcc(Jcc_Below, (void*)(uptr)func); + } + template + __fi void xJBE(T* func) + { + xJcc(Jcc_BelowOrEqual, (void*)(uptr)func); + } + template + __fi void xJA(T* func) + { + xJcc(Jcc_Above, (void*)(uptr)func); + } + template + __fi void xJAE(T* func) + { + xJcc(Jcc_AboveOrEqual, (void*)(uptr)func); + } + + // ------------------------------------------------------------------------ + // Forward Jump Helpers (act as labels!) + +#define DEFINE_FORWARD_JUMP(label, cond) \ + template \ + class xForward##label : public xForwardJump \ + { \ + public: \ + xForward##label() \ + : xForwardJump(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 xForwardJump8; + typedef xForwardJump 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 xForwardJA8; + typedef xForwardJA xForwardJA32; + typedef xForwardJB xForwardJB8; + typedef xForwardJB xForwardJB32; + typedef xForwardJAE xForwardJAE8; + typedef xForwardJAE xForwardJAE32; + typedef xForwardJBE xForwardJBE8; + typedef xForwardJBE 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 xForwardJG8; + typedef xForwardJG xForwardJG32; + typedef xForwardJL xForwardJL8; + typedef xForwardJL xForwardJL32; + typedef xForwardJGE xForwardJGE8; + typedef xForwardJGE xForwardJGE32; + typedef xForwardJLE xForwardJLE8; + typedef xForwardJLE 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 xForwardJZ8; + typedef xForwardJZ xForwardJZ32; + typedef xForwardJE xForwardJE8; + typedef xForwardJE xForwardJE32; + typedef xForwardJNZ xForwardJNZ8; + typedef xForwardJNZ xForwardJNZ32; + typedef xForwardJNE xForwardJNE8; + typedef xForwardJNE xForwardJNE32; + + DEFINE_FORWARD_JUMP(JS, Jcc_Signed); + DEFINE_FORWARD_JUMP(JNS, Jcc_Unsigned); + + typedef xForwardJS xForwardJS8; + typedef xForwardJS xForwardJS32; + typedef xForwardJNS xForwardJNS8; + typedef xForwardJNS xForwardJNS32; + + DEFINE_FORWARD_JUMP(JO, Jcc_Overflow); + DEFINE_FORWARD_JUMP(JNO, Jcc_NotOverflow); + + typedef xForwardJO xForwardJO8; + typedef xForwardJO xForwardJO32; + typedef xForwardJNO xForwardJNO8; + typedef xForwardJNO xForwardJNO32; + + DEFINE_FORWARD_JUMP(JC, Jcc_Carry); + DEFINE_FORWARD_JUMP(JNC, Jcc_NotCarry); + + typedef xForwardJC xForwardJC8; + typedef xForwardJC xForwardJC32; + typedef xForwardJNC xForwardJNC8; + typedef xForwardJNC xForwardJNC32; + + DEFINE_FORWARD_JUMP(JPE, Jcc_ParityEven); + DEFINE_FORWARD_JUMP(JPO, Jcc_ParityOdd); + + typedef xForwardJPE xForwardJPE8; + typedef xForwardJPE xForwardJPE32; + typedef xForwardJPO xForwardJPO8; + typedef xForwardJPO 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 xRegister32& to, const xRegisterSSE& from); + extern void xMOVMSKPD(const xRegister32& 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; + extern const xImplSimd_MoveSSE xMOVDQA; + extern const xImplSimd_MoveSSE xMOVDQU; #else -extern const xImplSimd_MoveDQ xMOVDQA; -extern const xImplSimd_MoveDQ xMOVDQU; + 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_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_Blend xBLEND; + extern const xImplSimd_PMove xPMOVSX; + extern const xImplSimd_PMove xPMOVZX; -extern const xImplSimd_DestRegSSE xMOVSLDUP; -extern const xImplSimd_DestRegSSE xMOVSHDUP; + 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 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 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_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_Shuffle xSHUF; -// ------------------------------------------------------------------------ + // ------------------------------------------------------------------------ -extern const xImplSimd_DestRegSSE xPTEST; + extern const xImplSimd_DestRegSSE xPTEST; -extern const xImplSimd_MinMax xMIN; -extern const xImplSimd_MinMax xMAX; + 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_Compare xCMPEQ, xCMPLT, + xCMPLE, xCMPUNORD, + xCMPNE, xCMPNLT, + xCMPNLE, xCMPORD; -extern const xImplSimd_COMI xCOMI; -extern const xImplSimd_COMI xUCOMI; + 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 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 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 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 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 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 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 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 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 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_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_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 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; +} // namespace x86Emitter diff --git a/common/emitter/internal.h b/common/emitter/internal.h index 2687b48673..1ad8f129b9 100644 --- a/common/emitter/internal.h +++ b/common/emitter/internal.h @@ -23,165 +23,168 @@ namespace x86Emitter #define OpWriteSSE(pre, op) xOpWrite0F(pre, op, to, from) -extern void SimdPrefix(u8 prefix, u16 opcode); -extern void EmitSibMagic(uint regfield, const void *address, int extraRIPOffset = 0); -extern void EmitSibMagic(uint regfield, const xIndirectVoid &info, int extraRIPOffset = 0); -extern void EmitSibMagic(uint reg1, const xRegisterBase ®2, int = 0); -extern void EmitSibMagic(const xRegisterBase ®1, const xRegisterBase ®2, int = 0); -extern void EmitSibMagic(const xRegisterBase ®1, const void *src, int extraRIPOffset = 0); -extern void EmitSibMagic(const xRegisterBase ®1, const xIndirectVoid &sib, int extraRIPOffset = 0); + extern void SimdPrefix(u8 prefix, u16 opcode); + extern void EmitSibMagic(uint regfield, const void* address, int extraRIPOffset = 0); + extern void EmitSibMagic(uint regfield, const xIndirectVoid& info, int extraRIPOffset = 0); + extern void EmitSibMagic(uint reg1, const xRegisterBase& reg2, int = 0); + extern void EmitSibMagic(const xRegisterBase& reg1, const xRegisterBase& reg2, int = 0); + extern void EmitSibMagic(const xRegisterBase& reg1, const void* src, int extraRIPOffset = 0); + extern void EmitSibMagic(const xRegisterBase& reg1, const xIndirectVoid& sib, int extraRIPOffset = 0); -extern void EmitRex(uint regfield, const void *address); -extern void EmitRex(uint regfield, const xIndirectVoid &info); -extern void EmitRex(uint reg1, const xRegisterBase ®2); -extern void EmitRex(const xRegisterBase ®1, const xRegisterBase ®2); -extern void EmitRex(const xRegisterBase ®1, const void *src); -extern void EmitRex(const xRegisterBase ®1, 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); + extern void _xMovRtoR(const xRegisterInt& to, const xRegisterInt& from); -template -inline void xWrite(T val) -{ - *(T *)x86Ptr = val; - x86Ptr += sizeof(T); -} + template + inline void xWrite(T val) + { + *(T*)x86Ptr = val; + x86Ptr += sizeof(T); + } -template -__emitinline void xOpWrite(u8 prefix, u8 opcode, const T1 ¶m1, const T2 ¶m2, int extraRIPOffset = 0) -{ - if (prefix != 0) - xWrite8(prefix); - EmitRex(param1, param2); + template + __emitinline void xOpWrite(u8 prefix, u8 opcode, const T1& param1, const T2& param2, int extraRIPOffset = 0) + { + if (prefix != 0) + xWrite8(prefix); + EmitRex(param1, param2); - xWrite8(opcode); + xWrite8(opcode); - EmitSibMagic(param1, param2, extraRIPOffset); -} + EmitSibMagic(param1, param2, extraRIPOffset); + } -template -__emitinline void xOpAccWrite(u8 prefix, u8 opcode, const T1 ¶m1, const T2 ¶m2) -{ - if (prefix != 0) - xWrite8(prefix); - EmitRex(param1, param2); + template + __emitinline void xOpAccWrite(u8 prefix, u8 opcode, const T1& param1, const T2& param2) + { + if (prefix != 0) + xWrite8(prefix); + EmitRex(param1, param2); - xWrite8(opcode); -} + 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 -__emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1 ¶m1, const T2 ¶m2) -{ - if (prefix != 0) - xWrite8(prefix); - EmitRex(param1, param2); + ////////////////////////////////////////////////////////////////////////////////////////// + // 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 + __emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1& param1, const T2& param2) + { + if (prefix != 0) + xWrite8(prefix); + EmitRex(param1, param2); - SimdPrefix(0, opcode); + SimdPrefix(0, opcode); - EmitSibMagic(param1, param2); -} + EmitSibMagic(param1, param2); + } -template -__emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1 ¶m1, const T2 ¶m2, u8 imm8) -{ - if (prefix != 0) - xWrite8(prefix); - EmitRex(param1, param2); + template + __emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1& param1, const T2& param2, u8 imm8) + { + if (prefix != 0) + xWrite8(prefix); + EmitRex(param1, param2); - SimdPrefix(0, opcode); + SimdPrefix(0, opcode); - EmitSibMagic(param1, param2, 1); - xWrite8(imm8); -} + EmitSibMagic(param1, param2, 1); + xWrite8(imm8); + } -template -__emitinline void xOpWrite0F(u16 opcode, const T1 ¶m1, const T2 ¶m2) -{ - xOpWrite0F(0, opcode, param1, param2); -} + template + __emitinline void xOpWrite0F(u16 opcode, const T1& param1, const T2& param2) + { + xOpWrite0F(0, opcode, param1, param2); + } -template -__emitinline void xOpWrite0F(u16 opcode, const T1 ¶m1, const T2 ¶m2, u8 imm8) -{ - xOpWrite0F(0, opcode, param1, param2, imm8); -} + template + __emitinline void xOpWrite0F(u16 opcode, const T1& param1, const T2& param2, u8 imm8) + { + xOpWrite0F(0, opcode, param1, param2, imm8); + } -// VEX 2 Bytes Prefix -template -__emitinline void xOpWriteC5(u8 prefix, u8 opcode, const T1 ¶m1, const T2 ¶m2, const T3 ¶m3) -{ - pxAssert(prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2); + // VEX 2 Bytes Prefix + template + __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 ® = param1.IsReg() ? param1 : param2; + const xRegisterInt& reg = param1.IsReg() ? param1 : param2; #ifdef __M_X86_64 - u8 nR = reg.IsExtended() ? 0x00 : 0x80; + u8 nR = reg.IsExtended() ? 0x00 : 0x80; #else - u8 nR = 0x80; + u8 nR = 0x80; #endif - u8 L = reg.IsWideSIMD() ? 4 : 0; + u8 L = reg.IsWideSIMD() ? 4 : 0; - u8 nv = (~param2.GetId() & 0xF) << 3; + u8 nv = (~param2.GetId() & 0xF) << 3; - u8 p = - prefix == 0xF2 ? 3 : - prefix == 0xF3 ? 2 : - prefix == 0x66 ? 1 : 0; + u8 p = + prefix == 0xF2 ? 3 : + prefix == 0xF3 ? 2 : + prefix == 0x66 ? 1 : + 0; - xWrite8(0xC5); - xWrite8(nR | nv | L | p); - xWrite8(opcode); - EmitSibMagic(param1, param3); -} + xWrite8(0xC5); + xWrite8(nR | nv | L | p); + xWrite8(opcode); + EmitSibMagic(param1, param3); + } -// VEX 3 Bytes Prefix -template -__emitinline void xOpWriteC4(u8 prefix, u8 mb_prefix, u8 opcode, const T1 ¶m1, const T2 ¶m2, const T3 ¶m3, int w = -1) -{ - pxAssert(prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2); - pxAssert(mb_prefix == 0x0F || mb_prefix == 0x38 || mb_prefix == 0x3A); + // VEX 3 Bytes Prefix + template + __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 ® = param1.IsReg() ? param1 : param2; + const xRegisterInt& reg = param1.IsReg() ? param1 : param2; #ifdef __M_X86_64 - u8 nR = reg.IsExtended() ? 0x00 : 0x80; - u8 nB = param3.IsExtended() ? 0x00 : 0x20; - u8 nX = 0x40; // likely unused so hardwired to disabled + 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; + 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 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 nv = (~param2.GetId() & 0xF) << 3; - u8 p = - prefix == 0xF2 ? 3 : - prefix == 0xF3 ? 2 : - prefix == 0x66 ? 1 : 0; + u8 p = + prefix == 0xF2 ? 3 : + prefix == 0xF3 ? 2 : + prefix == 0x66 ? 1 : + 0; - u8 m = - mb_prefix == 0x3A ? 3 : - mb_prefix == 0x38 ? 2 : 1; + 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); -} -} + xWrite8(0xC4); + xWrite8(nR | nX | nB | m); + xWrite8(W | nv | L | p); + xWrite8(opcode); + EmitSibMagic(param1, param3); + } +} // namespace x86Emitter diff --git a/common/emitter/jmp.cpp b/common/emitter/jmp.cpp index c301c29a23..d504583771 100644 --- a/common/emitter/jmp.cpp +++ b/common/emitter/jmp.cpp @@ -33,215 +33,253 @@ namespace x86Emitter { -void xImpl_JmpCall::operator()(const xAddressReg &absreg) const { - // Jumps are always wide and don't need the rex.W - xOpWrite(0, 0xff, isJmp ? 4 : 2, absreg.GetNonWide()); -} -void xImpl_JmpCall::operator()(const xIndirectNative &src) const { - // Jumps are always wide and don't need the rex.W - EmitRex(0, xIndirect32(src.Base, src.Index, 1, 0)); - xWrite8(0xff); - EmitSibMagic(isJmp ? 4 : 2, src); -} + void xImpl_JmpCall::operator()(const xAddressReg& absreg) const + { + // Jumps are always wide and don't need the rex.W + xOpWrite(0, 0xff, isJmp ? 4 : 2, absreg.GetNonWide()); + } + void xImpl_JmpCall::operator()(const xIndirectNative& src) const + { + // Jumps are always wide and don't need the rex.W + EmitRex(0, xIndirect32(src.Base, src.Index, 1, 0)); + xWrite8(0xff); + EmitSibMagic(isJmp ? 4 : 2, src); + } -const xImpl_JmpCall xJMP = {true}; -const xImpl_JmpCall xCALL = {false}; + const xImpl_JmpCall xJMP = {true}; + const xImpl_JmpCall xCALL = {false}; -template -void prepareRegsForFastcall(const Reg1 &a1, const Reg2 &a2) { - if (a1.IsEmpty()) return; + template + void prepareRegsForFastcall(const Reg1& a1, const Reg2& a2) + { + if (a1.IsEmpty()) + return; - // Make sure we don't mess up if someone tries to fastcall with a1 in arg2reg and a2 in arg1reg - if (a2.Id != arg1reg.Id) { - xMOV(Reg1(arg1reg), a1); - if (!a2.IsEmpty()) { - xMOV(Reg2(arg2reg), a2); - } - } else if (a1.Id != arg2reg.Id) { - xMOV(Reg2(arg2reg), a2); - xMOV(Reg1(arg1reg), a1); - } else { - xPUSH(a1); - xMOV(Reg2(arg2reg), a2); - xPOP(Reg1(arg1reg)); - } -} + // Make sure we don't mess up if someone tries to fastcall with a1 in arg2reg and a2 in arg1reg + if (a2.Id != arg1reg.Id) + { + xMOV(Reg1(arg1reg), a1); + if (!a2.IsEmpty()) + { + xMOV(Reg2(arg2reg), a2); + } + } + else if (a1.Id != arg2reg.Id) + { + xMOV(Reg2(arg2reg), a2); + xMOV(Reg1(arg1reg), a1); + } + else + { + xPUSH(a1); + xMOV(Reg2(arg2reg), a2); + xPOP(Reg1(arg1reg)); + } + } -void xImpl_FastCall::operator()(void *f, const xRegister32 &a1, const xRegister32 &a2) const { - prepareRegsForFastcall(a1, a2); - uptr disp = ((uptr)xGetPtr() + 5) - (uptr)f; - if ((sptr)disp == (s32)disp) { - xCALL(f); - } else { - xMOV(rax, ptrNative[f]); - xCALL(rax); - } -} + void xImpl_FastCall::operator()(void* f, const xRegister32& a1, const xRegister32& a2) const + { + prepareRegsForFastcall(a1, a2); + uptr disp = ((uptr)xGetPtr() + 5) - (uptr)f; + if ((sptr)disp == (s32)disp) + { + xCALL(f); + } + else + { + xMOV(rax, ptrNative[f]); + xCALL(rax); + } + } #ifdef __M_X86_64 -void xImpl_FastCall::operator()(void *f, const xRegisterLong &a1, const xRegisterLong &a2) const { - prepareRegsForFastcall(a1, a2); - uptr disp = ((uptr)xGetPtr() + 5) - (uptr)f; - if ((sptr)disp == (s32)disp) { - xCALL(f); - } else { - xMOV(rax, ptrNative[f]); - xCALL(rax); - } -} + void xImpl_FastCall::operator()(void* f, const xRegisterLong& a1, const xRegisterLong& a2) const + { + prepareRegsForFastcall(a1, a2); + uptr disp = ((uptr)xGetPtr() + 5) - (uptr)f; + if ((sptr)disp == (s32)disp) + { + xCALL(f); + } + else + { + xMOV(rax, ptrNative[f]); + xCALL(rax); + } + } -void xImpl_FastCall::operator()(void *f, u32 a1, const xRegisterLong &a2) const { - if (!a2.IsEmpty()) { xMOV(arg2reg, a2); } - xMOV(arg1reg, a1); - (*this)(f, arg1reg, arg2reg); -} + void xImpl_FastCall::operator()(void* f, u32 a1, const xRegisterLong& a2) const + { + if (!a2.IsEmpty()) + { + xMOV(arg2reg, a2); + } + xMOV(arg1reg, a1); + (*this)(f, arg1reg, arg2reg); + } #endif -void xImpl_FastCall::operator()(void *f, void *a1) const { - xLEA(arg1reg, ptr[a1]); - (*this)(f, arg1reg, arg2reg); -} + void xImpl_FastCall::operator()(void* f, void* a1) const + { + xLEA(arg1reg, ptr[a1]); + (*this)(f, arg1reg, arg2reg); + } -void xImpl_FastCall::operator()(void *f, u32 a1, const xRegister32 &a2) const { - if (!a2.IsEmpty()) { xMOV(arg2regd, a2); } - xMOV(arg1regd, a1); - (*this)(f, arg1regd, arg2regd); -} + void xImpl_FastCall::operator()(void* f, u32 a1, const xRegister32& a2) const + { + if (!a2.IsEmpty()) + { + xMOV(arg2regd, a2); + } + xMOV(arg1regd, a1); + (*this)(f, arg1regd, arg2regd); + } -void xImpl_FastCall::operator()(void *f, const xIndirect32 &a1) const { - xMOV(arg1regd, a1); - (*this)(f, arg1regd); -} + void xImpl_FastCall::operator()(void* f, const xIndirect32& a1) const + { + xMOV(arg1regd, a1); + (*this)(f, arg1regd); + } -void xImpl_FastCall::operator()(void *f, u32 a1, u32 a2) const { - xMOV(arg1regd, a1); - xMOV(arg2regd, a2); - (*this)(f, arg1regd, arg2regd); -} + void xImpl_FastCall::operator()(void* f, u32 a1, u32 a2) const + { + xMOV(arg1regd, a1); + xMOV(arg2regd, a2); + (*this)(f, arg1regd, arg2regd); + } -void xImpl_FastCall::operator()(const xIndirectNative &f, const xRegisterLong &a1, const xRegisterLong &a2) const { - prepareRegsForFastcall(a1, a2); - xCALL(f); -} + void xImpl_FastCall::operator()(const xIndirectNative& f, const xRegisterLong& a1, const xRegisterLong& a2) const + { + prepareRegsForFastcall(a1, a2); + xCALL(f); + } -const xImpl_FastCall xFastCall = {}; + const xImpl_FastCall xFastCall = {}; -// ------------------------------------------------------------------------ -// Emits a 32 bit jump, and returns a pointer to the 32 bit displacement. -// (displacements should be assigned relative to the end of the jump instruction, -// or in other words *(retval+1) ) -__emitinline s32 *xJcc32(JccComparisonType comparison, s32 displacement) -{ - if (comparison == Jcc_Unconditional) - xWrite8(0xe9); - else { - xWrite8(0x0f); - xWrite8(0x80 | comparison); - } - xWrite(displacement); + // ------------------------------------------------------------------------ + // Emits a 32 bit jump, and returns a pointer to the 32 bit displacement. + // (displacements should be assigned relative to the end of the jump instruction, + // or in other words *(retval+1) ) + __emitinline s32* xJcc32(JccComparisonType comparison, s32 displacement) + { + if (comparison == Jcc_Unconditional) + xWrite8(0xe9); + else + { + xWrite8(0x0f); + xWrite8(0x80 | comparison); + } + xWrite(displacement); - return ((s32 *)xGetPtr()) - 1; -} + return ((s32*)xGetPtr()) - 1; + } -// ------------------------------------------------------------------------ -// Emits a 32 bit jump, and returns a pointer to the 8 bit displacement. -// (displacements should be assigned relative to the end of the jump instruction, -// or in other words *(retval+1) ) -__emitinline s8 *xJcc8(JccComparisonType comparison, s8 displacement) -{ - xWrite8((comparison == Jcc_Unconditional) ? 0xeb : (0x70 | comparison)); - xWrite(displacement); - return (s8 *)xGetPtr() - 1; -} + // ------------------------------------------------------------------------ + // Emits a 32 bit jump, and returns a pointer to the 8 bit displacement. + // (displacements should be assigned relative to the end of the jump instruction, + // or in other words *(retval+1) ) + __emitinline s8* xJcc8(JccComparisonType comparison, s8 displacement) + { + xWrite8((comparison == Jcc_Unconditional) ? 0xeb : (0x70 | comparison)); + xWrite(displacement); + return (s8*)xGetPtr() - 1; + } -// ------------------------------------------------------------------------ -// Writes a jump at the current x86Ptr, which targets a pre-established target address. -// (usually a backwards jump) -// -// slideForward - used internally by xSmartJump to indicate that the jump target is going -// to slide forward in the event of an 8 bit displacement. -// -__emitinline void xJccKnownTarget(JccComparisonType comparison, const void *target, bool slideForward) -{ - // Calculate the potential j8 displacement first, assuming an instruction length of 2: - sptr displacement8 = (sptr)target - (sptr)(xGetPtr() + 2); + // ------------------------------------------------------------------------ + // Writes a jump at the current x86Ptr, which targets a pre-established target address. + // (usually a backwards jump) + // + // slideForward - used internally by xSmartJump to indicate that the jump target is going + // to slide forward in the event of an 8 bit displacement. + // + __emitinline void xJccKnownTarget(JccComparisonType comparison, const void* target, bool slideForward) + { + // Calculate the potential j8 displacement first, assuming an instruction length of 2: + sptr displacement8 = (sptr)target - (sptr)(xGetPtr() + 2); - const int slideVal = slideForward ? ((comparison == Jcc_Unconditional) ? 3 : 4) : 0; - displacement8 -= slideVal; + const int slideVal = slideForward ? ((comparison == Jcc_Unconditional) ? 3 : 4) : 0; + displacement8 -= slideVal; - if (slideForward) { - pxAssertDev(displacement8 >= 0, "Used slideForward on a backward jump; nothing to slide!"); - } + if (slideForward) + { + pxAssertDev(displacement8 >= 0, "Used slideForward on a backward jump; nothing to slide!"); + } - if (is_s8(displacement8)) - xJcc8(comparison, displacement8); - else { - // Perform a 32 bit jump instead. :( - s32 *bah = xJcc32(comparison); - sptr distance = (sptr)target - (sptr)xGetPtr(); + if (is_s8(displacement8)) + xJcc8(comparison, displacement8); + else + { + // Perform a 32 bit jump instead. :( + s32* bah = xJcc32(comparison); + sptr distance = (sptr)target - (sptr)xGetPtr(); #ifdef __M_X86_64 - // This assert won't physically happen on x86 targets - pxAssertDev(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target is too far away, needs an indirect register"); + // This assert won't physically happen on x86 targets + pxAssertDev(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target is too far away, needs an indirect register"); #endif - *bah = (s32)distance; - } -} + *bah = (s32)distance; + } + } -// Low-level jump instruction! Specify a comparison type and a target in void* form, and -// a jump (either 8 or 32 bit) is generated. -__emitinline void xJcc(JccComparisonType comparison, const void *target) -{ - xJccKnownTarget(comparison, target, false); -} + // Low-level jump instruction! Specify a comparison type and a target in void* form, and + // a jump (either 8 or 32 bit) is generated. + __emitinline void xJcc(JccComparisonType comparison, const void* target) + { + xJccKnownTarget(comparison, target, false); + } -xForwardJumpBase::xForwardJumpBase(uint opsize, JccComparisonType cctype) -{ - pxAssert(opsize == 1 || opsize == 4); - pxAssertDev(cctype != Jcc_Unknown, "Invalid ForwardJump conditional type."); + xForwardJumpBase::xForwardJumpBase(uint opsize, JccComparisonType cctype) + { + pxAssert(opsize == 1 || opsize == 4); + pxAssertDev(cctype != Jcc_Unknown, "Invalid ForwardJump conditional type."); - BasePtr = (s8 *)xGetPtr() + - ((opsize == 1) ? 2 : // j8's are always 2 bytes. - ((cctype == Jcc_Unconditional) ? 5 : 6)); // j32's are either 5 or 6 bytes + BasePtr = (s8*)xGetPtr() + + ((opsize == 1) ? 2 : // j8's are always 2 bytes. + ((cctype == Jcc_Unconditional) ? 5 : 6)); // j32's are either 5 or 6 bytes - if (opsize == 1) - xWrite8((cctype == Jcc_Unconditional) ? 0xeb : (0x70 | cctype)); - else { - if (cctype == Jcc_Unconditional) - xWrite8(0xe9); - else { - xWrite8(0x0f); - xWrite8(0x80 | cctype); - } - } + if (opsize == 1) + xWrite8((cctype == Jcc_Unconditional) ? 0xeb : (0x70 | cctype)); + else + { + if (cctype == Jcc_Unconditional) + xWrite8(0xe9); + else + { + xWrite8(0x0f); + xWrite8(0x80 | cctype); + } + } - xAdvancePtr(opsize); -} + xAdvancePtr(opsize); + } -void xForwardJumpBase::_setTarget(uint opsize) const -{ - pxAssertDev(BasePtr != NULL, ""); + void xForwardJumpBase::_setTarget(uint opsize) const + { + pxAssertDev(BasePtr != NULL, ""); - sptr displacement = (sptr)xGetPtr() - (sptr)BasePtr; - if (opsize == 1) { - pxAssertDev(is_s8(displacement), "Emitter Error: Invalid short jump displacement."); - BasePtr[-1] = (s8)displacement; - } else { - // full displacement, no sanity checks needed :D - ((s32 *)BasePtr)[-1] = displacement; - } -} + sptr displacement = (sptr)xGetPtr() - (sptr)BasePtr; + if (opsize == 1) + { + pxAssertDev(is_s8(displacement), "Emitter Error: Invalid short jump displacement."); + BasePtr[-1] = (s8)displacement; + } + else + { + // full displacement, no sanity checks needed :D + ((s32*)BasePtr)[-1] = displacement; + } + } -// returns the inverted conditional type for this Jcc condition. Ie, JNS will become JS. -__fi JccComparisonType xInvertCond(JccComparisonType src) -{ - pxAssert(src != Jcc_Unknown); - if (Jcc_Unconditional == src) - return Jcc_Unconditional; + // returns the inverted conditional type for this Jcc condition. Ie, JNS will become JS. + __fi JccComparisonType xInvertCond(JccComparisonType src) + { + pxAssert(src != Jcc_Unknown); + if (Jcc_Unconditional == src) + return Jcc_Unconditional; - // x86 conditionals are clever! To invert conditional types, just invert the lower bit: - return (JccComparisonType)((int)src ^ 1); -} -} + // x86 conditionals are clever! To invert conditional types, just invert the lower bit: + return (JccComparisonType)((int)src ^ 1); + } +} // namespace x86Emitter diff --git a/common/emitter/legacy.cpp b/common/emitter/legacy.cpp index f762172650..4d0715f945 100644 --- a/common/emitter/legacy.cpp +++ b/common/emitter/legacy.cpp @@ -29,24 +29,24 @@ emitterT void ModRM(uint mod, uint reg, uint rm) { - // Note: Following assertions are for legacy support only. - // The new emitter performs these sanity checks during operand construction, so these - // assertions can probably be removed once all legacy emitter code has been removed. - pxAssert(mod < 4); - pxAssert(reg < 8); - pxAssert(rm < 8); - xWrite8((mod << 6) | (reg << 3) | rm); + // Note: Following assertions are for legacy support only. + // The new emitter performs these sanity checks during operand construction, so these + // assertions can probably be removed once all legacy emitter code has been removed. + pxAssert(mod < 4); + pxAssert(reg < 8); + pxAssert(rm < 8); + xWrite8((mod << 6) | (reg << 3) | rm); } emitterT void SibSB(uint ss, uint index, uint base) { - // Note: Following asserts are for legacy support only. - // The new emitter performs these sanity checks during operand construction, so these - // assertions can probably be removed once all legacy emitter code has been removed. - pxAssert(ss < 4); - pxAssert(index < 8); - pxAssert(base < 8); - xWrite8((ss << 6) | (index << 3) | base); + // Note: Following asserts are for legacy support only. + // The new emitter performs these sanity checks during operand construction, so these + // assertions can probably be removed once all legacy emitter code has been removed. + pxAssert(ss < 4); + pxAssert(index < 8); + pxAssert(base < 8); + xWrite8((ss << 6) | (index << 3) | base); } using namespace x86Emitter; @@ -57,33 +57,33 @@ using namespace x86Emitter; ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// -emitterT u8 *J8Rel(int cc, int to) +emitterT u8* J8Rel(int cc, int to) { - xWrite8(cc); - xWrite8(to); - return (u8 *)(x86Ptr - 1); + xWrite8(cc); + xWrite8(to); + return (u8*)(x86Ptr - 1); } -emitterT u16 *J16Rel(int cc, u32 to) +emitterT u16* J16Rel(int cc, u32 to) { - xWrite16(0x0F66); - xWrite8(cc); - xWrite16(to); - return (u16 *)(x86Ptr - 2); + xWrite16(0x0F66); + xWrite8(cc); + xWrite16(to); + return (u16*)(x86Ptr - 2); } -emitterT u32 *J32Rel(int cc, u32 to) +emitterT u32* J32Rel(int cc, u32 to) { - xWrite8(0x0F); - xWrite8(cc); - xWrite32(to); - return (u32 *)(x86Ptr - 4); + xWrite8(0x0F); + xWrite8(cc); + xWrite32(to); + return (u32*)(x86Ptr - 4); } //////////////////////////////////////////////////// -emitterT void x86SetPtr(u8 *ptr) +emitterT void x86SetPtr(u8* ptr) { - x86Ptr = ptr; + x86Ptr = ptr; } ////////////////////////////////////////////////////////////////////////////////////////// @@ -92,57 +92,61 @@ emitterT void x86SetPtr(u8 *ptr) // I don't auto-inline these because of the console logging in case of error, which tends // to cause quite a bit of code bloat. // -void x86SetJ8(u8 *j8) +void x86SetJ8(u8* j8) { - u32 jump = (x86Ptr - j8) - 1; + u32 jump = (x86Ptr - j8) - 1; - if (jump > 0x7f) { - Console.Error("j8 greater than 0x7f!!"); - assert(0); - } - *j8 = (u8)jump; + if (jump > 0x7f) + { + Console.Error("j8 greater than 0x7f!!"); + assert(0); + } + *j8 = (u8)jump; } -void x86SetJ8A(u8 *j8) +void x86SetJ8A(u8* j8) { - u32 jump = (x86Ptr - j8) - 1; + u32 jump = (x86Ptr - j8) - 1; - if (jump > 0x7f) { - Console.Error("j8 greater than 0x7f!!"); - assert(0); - } + if (jump > 0x7f) + { + Console.Error("j8 greater than 0x7f!!"); + assert(0); + } - if (((uptr)x86Ptr & 0xf) > 4) { + if (((uptr)x86Ptr & 0xf) > 4) + { - uptr newjump = jump + 16 - ((uptr)x86Ptr & 0xf); + uptr newjump = jump + 16 - ((uptr)x86Ptr & 0xf); - if (newjump <= 0x7f) { - jump = newjump; - while ((uptr)x86Ptr & 0xf) - *x86Ptr++ = 0x90; - } - } - *j8 = (u8)jump; + if (newjump <= 0x7f) + { + jump = newjump; + while ((uptr)x86Ptr & 0xf) + *x86Ptr++ = 0x90; + } + } + *j8 = (u8)jump; } //////////////////////////////////////////////////// -emitterT void x86SetJ32(u32 *j32) +emitterT void x86SetJ32(u32* j32) { - *j32 = (x86Ptr - (u8 *)j32) - 4; + *j32 = (x86Ptr - (u8*)j32) - 4; } -emitterT void x86SetJ32A(u32 *j32) +emitterT void x86SetJ32A(u32* j32) { - while ((uptr)x86Ptr & 0xf) - *x86Ptr++ = 0x90; - x86SetJ32(j32); + while ((uptr)x86Ptr & 0xf) + *x86Ptr++ = 0x90; + x86SetJ32(j32); } //////////////////////////////////////////////////// emitterT void x86Align(int bytes) { - // forward align - x86Ptr = (u8 *)(((uptr)x86Ptr + bytes - 1) & ~(bytes - 1)); + // forward align + x86Ptr = (u8*)(((uptr)x86Ptr + bytes - 1) & ~(bytes - 1)); } /********************/ @@ -154,262 +158,262 @@ emitterT void x86Align(int bytes) //////////////////////////////////// /* jmp rel8 */ -emitterT u8 *JMP8(u8 to) +emitterT u8* JMP8(u8 to) { - xWrite8(0xEB); - xWrite8(to); - return x86Ptr - 1; + xWrite8(0xEB); + xWrite8(to); + return x86Ptr - 1; } /* jmp rel32 */ -emitterT u32 *JMP32(uptr to) +emitterT u32* JMP32(uptr to) { - assert((sptr)to <= 0x7fffffff && (sptr)to >= -0x7fffffff); - xWrite8(0xE9); - xWrite32(to); - return (u32 *)(x86Ptr - 4); + assert((sptr)to <= 0x7fffffff && (sptr)to >= -0x7fffffff); + xWrite8(0xE9); + xWrite32(to); + return (u32*)(x86Ptr - 4); } /* jp rel8 */ -emitterT u8 *JP8(u8 to) +emitterT u8* JP8(u8 to) { - return J8Rel(0x7A, to); + return J8Rel(0x7A, to); } /* jnp rel8 */ -emitterT u8 *JNP8(u8 to) +emitterT u8* JNP8(u8 to) { - return J8Rel(0x7B, to); + return J8Rel(0x7B, to); } /* je rel8 */ -emitterT u8 *JE8(u8 to) +emitterT u8* JE8(u8 to) { - return J8Rel(0x74, to); + return J8Rel(0x74, to); } /* jz rel8 */ -emitterT u8 *JZ8(u8 to) +emitterT u8* JZ8(u8 to) { - return J8Rel(0x74, to); + return J8Rel(0x74, to); } /* js rel8 */ -emitterT u8 *JS8(u8 to) +emitterT u8* JS8(u8 to) { - return J8Rel(0x78, to); + return J8Rel(0x78, to); } /* jns rel8 */ -emitterT u8 *JNS8(u8 to) +emitterT u8* JNS8(u8 to) { - return J8Rel(0x79, to); + return J8Rel(0x79, to); } /* jg rel8 */ -emitterT u8 *JG8(u8 to) +emitterT u8* JG8(u8 to) { - return J8Rel(0x7F, to); + return J8Rel(0x7F, to); } /* jge rel8 */ -emitterT u8 *JGE8(u8 to) +emitterT u8* JGE8(u8 to) { - return J8Rel(0x7D, to); + return J8Rel(0x7D, to); } /* jl rel8 */ -emitterT u8 *JL8(u8 to) +emitterT u8* JL8(u8 to) { - return J8Rel(0x7C, to); + return J8Rel(0x7C, to); } /* ja rel8 */ -emitterT u8 *JA8(u8 to) +emitterT u8* JA8(u8 to) { - return J8Rel(0x77, to); + return J8Rel(0x77, to); } -emitterT u8 *JAE8(u8 to) +emitterT u8* JAE8(u8 to) { - return J8Rel(0x73, to); + return J8Rel(0x73, to); } /* jb rel8 */ -emitterT u8 *JB8(u8 to) +emitterT u8* JB8(u8 to) { - return J8Rel(0x72, to); + return J8Rel(0x72, to); } /* jbe rel8 */ -emitterT u8 *JBE8(u8 to) +emitterT u8* JBE8(u8 to) { - return J8Rel(0x76, to); + return J8Rel(0x76, to); } /* jle rel8 */ -emitterT u8 *JLE8(u8 to) +emitterT u8* JLE8(u8 to) { - return J8Rel(0x7E, to); + return J8Rel(0x7E, to); } /* jne rel8 */ -emitterT u8 *JNE8(u8 to) +emitterT u8* JNE8(u8 to) { - return J8Rel(0x75, to); + return J8Rel(0x75, to); } /* jnz rel8 */ -emitterT u8 *JNZ8(u8 to) +emitterT u8* JNZ8(u8 to) { - return J8Rel(0x75, to); + return J8Rel(0x75, to); } /* jng rel8 */ -emitterT u8 *JNG8(u8 to) +emitterT u8* JNG8(u8 to) { - return J8Rel(0x7E, to); + return J8Rel(0x7E, to); } /* jnge rel8 */ -emitterT u8 *JNGE8(u8 to) +emitterT u8* JNGE8(u8 to) { - return J8Rel(0x7C, to); + return J8Rel(0x7C, to); } /* jnl rel8 */ -emitterT u8 *JNL8(u8 to) +emitterT u8* JNL8(u8 to) { - return J8Rel(0x7D, to); + return J8Rel(0x7D, to); } /* jnle rel8 */ -emitterT u8 *JNLE8(u8 to) +emitterT u8* JNLE8(u8 to) { - return J8Rel(0x7F, to); + return J8Rel(0x7F, to); } /* jo rel8 */ -emitterT u8 *JO8(u8 to) +emitterT u8* JO8(u8 to) { - return J8Rel(0x70, to); + return J8Rel(0x70, to); } /* jno rel8 */ -emitterT u8 *JNO8(u8 to) +emitterT u8* JNO8(u8 to) { - return J8Rel(0x71, to); + return J8Rel(0x71, to); } // jb rel32 -emitterT u32 *JB32(u32 to) +emitterT u32* JB32(u32 to) { - return J32Rel(0x82, to); + return J32Rel(0x82, to); } /* je rel32 */ -emitterT u32 *JE32(u32 to) +emitterT u32* JE32(u32 to) { - return J32Rel(0x84, to); + return J32Rel(0x84, to); } /* jz rel32 */ -emitterT u32 *JZ32(u32 to) +emitterT u32* JZ32(u32 to) { - return J32Rel(0x84, to); + return J32Rel(0x84, to); } /* js rel32 */ -emitterT u32 *JS32(u32 to) +emitterT u32* JS32(u32 to) { - return J32Rel(0x88, to); + return J32Rel(0x88, to); } /* jns rel32 */ -emitterT u32 *JNS32(u32 to) +emitterT u32* JNS32(u32 to) { - return J32Rel(0x89, to); + return J32Rel(0x89, to); } /* jg rel32 */ -emitterT u32 *JG32(u32 to) +emitterT u32* JG32(u32 to) { - return J32Rel(0x8F, to); + return J32Rel(0x8F, to); } /* jge rel32 */ -emitterT u32 *JGE32(u32 to) +emitterT u32* JGE32(u32 to) { - return J32Rel(0x8D, to); + return J32Rel(0x8D, to); } /* jl rel32 */ -emitterT u32 *JL32(u32 to) +emitterT u32* JL32(u32 to) { - return J32Rel(0x8C, to); + return J32Rel(0x8C, to); } /* jle rel32 */ -emitterT u32 *JLE32(u32 to) +emitterT u32* JLE32(u32 to) { - return J32Rel(0x8E, to); + return J32Rel(0x8E, to); } /* ja rel32 */ -emitterT u32 *JA32(u32 to) +emitterT u32* JA32(u32 to) { - return J32Rel(0x87, to); + return J32Rel(0x87, to); } /* jae rel32 */ -emitterT u32 *JAE32(u32 to) +emitterT u32* JAE32(u32 to) { - return J32Rel(0x83, to); + return J32Rel(0x83, to); } /* jne rel32 */ -emitterT u32 *JNE32(u32 to) +emitterT u32* JNE32(u32 to) { - return J32Rel(0x85, to); + return J32Rel(0x85, to); } /* jnz rel32 */ -emitterT u32 *JNZ32(u32 to) +emitterT u32* JNZ32(u32 to) { - return J32Rel(0x85, to); + return J32Rel(0x85, to); } /* jng rel32 */ -emitterT u32 *JNG32(u32 to) +emitterT u32* JNG32(u32 to) { - return J32Rel(0x8E, to); + return J32Rel(0x8E, to); } /* jnge rel32 */ -emitterT u32 *JNGE32(u32 to) +emitterT u32* JNGE32(u32 to) { - return J32Rel(0x8C, to); + return J32Rel(0x8C, to); } /* jnl rel32 */ -emitterT u32 *JNL32(u32 to) +emitterT u32* JNL32(u32 to) { - return J32Rel(0x8D, to); + return J32Rel(0x8D, to); } /* jnle rel32 */ -emitterT u32 *JNLE32(u32 to) +emitterT u32* JNLE32(u32 to) { - return J32Rel(0x8F, to); + return J32Rel(0x8F, to); } /* jo rel32 */ -emitterT u32 *JO32(u32 to) +emitterT u32* JO32(u32 to) { - return J32Rel(0x80, to); + return J32Rel(0x80, to); } /* jno rel32 */ -emitterT u32 *JNO32(u32 to) +emitterT u32* JNO32(u32 to) { - return J32Rel(0x81, to); + return J32Rel(0x81, to); } diff --git a/common/emitter/legacy_instructions.h b/common/emitter/legacy_instructions.h index e17e2ff704..fdd9304cf1 100644 --- a/common/emitter/legacy_instructions.h +++ b/common/emitter/legacy_instructions.h @@ -25,13 +25,13 @@ //------------------------------------------------------------------ // 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 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,44 +103,44 @@ 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 diff --git a/common/emitter/legacy_internal.h b/common/emitter/legacy_internal.h index ba5f0d6464..ab4459db8a 100644 --- a/common/emitter/legacy_internal.h +++ b/common/emitter/legacy_internal.h @@ -36,5 +36,5 @@ using x86Emitter::xWrite64; 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); +extern u8* J8Rel(int cc, int to); +extern u32* J32Rel(int cc, u32 to); diff --git a/common/emitter/movs.cpp b/common/emitter/movs.cpp index 326fab239d..447996afe8 100644 --- a/common/emitter/movs.cpp +++ b/common/emitter/movs.cpp @@ -34,132 +34,146 @@ namespace x86Emitter { -void _xMovRtoR(const xRegisterInt &to, const xRegisterInt &from) -{ - pxAssert(to.GetOperandSize() == from.GetOperandSize()); + void _xMovRtoR(const xRegisterInt& to, const xRegisterInt& from) + { + pxAssert(to.GetOperandSize() == from.GetOperandSize()); - if (to == from) - return; // ignore redundant MOVs. + if (to == from) + return; // ignore redundant MOVs. - xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, to); -} + xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, to); + } -void xImpl_Mov::operator()(const xRegisterInt &to, const xRegisterInt &from) const -{ - // FIXME WTF? - _xMovRtoR(to, from); -} + void xImpl_Mov::operator()(const xRegisterInt& to, const xRegisterInt& from) const + { + // FIXME WTF? + _xMovRtoR(to, from); + } -void xImpl_Mov::operator()(const xIndirectVoid &dest, const xRegisterInt &from) const -{ - // mov eax has a special from when writing directly to a DISP32 address - // (sans any register index/base registers). + void xImpl_Mov::operator()(const xIndirectVoid& dest, const xRegisterInt& from) const + { + // mov eax has a special from when writing directly to a DISP32 address + // (sans any register index/base registers). #ifndef __M_X86_64 - // Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr - if (from.IsAccumulator() && dest.Index.IsEmpty() && dest.Base.IsEmpty()) { - xOpAccWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xa2 : 0xa3, from, dest); - xWrite32(dest.Displacement); - } else + // Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr + if (from.IsAccumulator() && dest.Index.IsEmpty() && dest.Base.IsEmpty()) + { + xOpAccWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xa2 : 0xa3, from, dest); + xWrite32(dest.Displacement); + } + else #endif - { - xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, dest); - } -} + { + xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, dest); + } + } -void xImpl_Mov::operator()(const xRegisterInt &to, const xIndirectVoid &src) const -{ - // mov eax has a special from when reading directly from a DISP32 address - // (sans any register index/base registers). + void xImpl_Mov::operator()(const xRegisterInt& to, const xIndirectVoid& src) const + { + // mov eax has a special from when reading directly from a DISP32 address + // (sans any register index/base registers). #ifndef __M_X86_64 - // Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr - if (to.IsAccumulator() && src.Index.IsEmpty() && src.Base.IsEmpty()) { - xOpAccWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xa0 : 0xa1, to, src); - xWrite32(src.Displacement); - } else + // Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr + if (to.IsAccumulator() && src.Index.IsEmpty() && src.Base.IsEmpty()) + { + xOpAccWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xa0 : 0xa1, to, src); + xWrite32(src.Displacement); + } + else #endif - { - xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0x8a : 0x8b, to, src); - } -} + { + xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0x8a : 0x8b, to, src); + } + } -void xImpl_Mov::operator()(const xIndirect64orLess &dest, sptr imm) const -{ - switch (dest.GetOperandSize()) { - case 1: - pxAssertMsg(imm == (s8)imm || imm == (u8)imm, "Immediate won't fit!"); - break; - case 2: - pxAssertMsg(imm == (s16)imm || imm == (u16)imm, "Immediate won't fit!"); - break; - case 4: - pxAssertMsg(imm == (s32)imm || imm == (u32)imm, "Immediate won't fit!"); - break; - case 8: - pxAssertMsg(imm == (s32)imm, "Immediate won't fit in immediate slot, go through a register!"); - break; - default: - pxAssertMsg(0, "Bad indirect size!"); - } - xOpWrite(dest.GetPrefix16(), dest.Is8BitOp() ? 0xc6 : 0xc7, 0, dest, dest.GetImmSize()); - dest.xWriteImm(imm); -} + void xImpl_Mov::operator()(const xIndirect64orLess& dest, sptr imm) const + { + switch (dest.GetOperandSize()) + { + case 1: + pxAssertMsg(imm == (s8)imm || imm == (u8)imm, "Immediate won't fit!"); + break; + case 2: + pxAssertMsg(imm == (s16)imm || imm == (u16)imm, "Immediate won't fit!"); + break; + case 4: + pxAssertMsg(imm == (s32)imm || imm == (u32)imm, "Immediate won't fit!"); + break; + case 8: + pxAssertMsg(imm == (s32)imm, "Immediate won't fit in immediate slot, go through a register!"); + break; + default: + pxAssertMsg(0, "Bad indirect size!"); + } + xOpWrite(dest.GetPrefix16(), dest.Is8BitOp() ? 0xc6 : 0xc7, 0, dest, dest.GetImmSize()); + dest.xWriteImm(imm); + } -// preserve_flags - set to true to disable optimizations which could alter the state of -// the flags (namely replacing mov reg,0 with xor). -void xImpl_Mov::operator()(const xRegisterInt &to, sptr imm, bool preserve_flags) const -{ - switch (to.GetOperandSize()) { - case 1: - pxAssertMsg(imm == (s8)imm || imm == (u8)imm, "Immediate won't fit!"); - break; - case 2: - pxAssertMsg(imm == (s16)imm || imm == (u16)imm, "Immediate won't fit!"); - break; - case 4: - pxAssertMsg(imm == (s32)imm || imm == (u32)imm, "Immediate won't fit!"); - break; - case 8: - pxAssertMsg(imm == (s32)imm || imm == (u32)imm, "Immediate won't fit in immediate slot, use mov64 or lea!"); - break; - default: - pxAssertMsg(0, "Bad indirect size!"); - } - const xRegisterInt& to_ = to.GetNonWide(); - if (!preserve_flags && (imm == 0)) { - _g1_EmitOp(G1Type_XOR, to_, to_); - } else if (imm == (u32)imm || !to.IsWide()) { - // Note: MOV does not have (reg16/32,imm8) forms. - u8 opcode = (to_.Is8BitOp() ? 0xb0 : 0xb8) | to_.Id; - xOpAccWrite(to_.GetPrefix16(), opcode, 0, to_); - to_.xWriteImm(imm); - } else { - xOpWrite(to.GetPrefix16(), 0xc7, 0, to); - to.xWriteImm(imm); - } -} + // preserve_flags - set to true to disable optimizations which could alter the state of + // the flags (namely replacing mov reg,0 with xor). + void xImpl_Mov::operator()(const xRegisterInt& to, sptr imm, bool preserve_flags) const + { + switch (to.GetOperandSize()) + { + case 1: + pxAssertMsg(imm == (s8)imm || imm == (u8)imm, "Immediate won't fit!"); + break; + case 2: + pxAssertMsg(imm == (s16)imm || imm == (u16)imm, "Immediate won't fit!"); + break; + case 4: + pxAssertMsg(imm == (s32)imm || imm == (u32)imm, "Immediate won't fit!"); + break; + case 8: + pxAssertMsg(imm == (s32)imm || imm == (u32)imm, "Immediate won't fit in immediate slot, use mov64 or lea!"); + break; + default: + pxAssertMsg(0, "Bad indirect size!"); + } + const xRegisterInt& to_ = to.GetNonWide(); + if (!preserve_flags && (imm == 0)) + { + _g1_EmitOp(G1Type_XOR, to_, to_); + } + else if (imm == (u32)imm || !to.IsWide()) + { + // Note: MOV does not have (reg16/32,imm8) forms. + u8 opcode = (to_.Is8BitOp() ? 0xb0 : 0xb8) | to_.Id; + xOpAccWrite(to_.GetPrefix16(), opcode, 0, to_); + to_.xWriteImm(imm); + } + else + { + xOpWrite(to.GetPrefix16(), 0xc7, 0, to); + to.xWriteImm(imm); + } + } -const xImpl_Mov xMOV; + const xImpl_Mov xMOV; #ifdef __M_X86_64 -void xImpl_MovImm64::operator()(const xRegister64& to, s64 imm, bool preserve_flags) const -{ - if (imm == (u32)imm || imm == (s32)imm) { - xMOV(to, imm, preserve_flags); - } else { - u8 opcode = 0xb8 | to.Id; - xOpAccWrite(to.GetPrefix16(), opcode, 0, to); - xWrite64(imm); - } -} + void xImpl_MovImm64::operator()(const xRegister64& to, s64 imm, bool preserve_flags) const + { + if (imm == (u32)imm || imm == (s32)imm) + { + xMOV(to, imm, preserve_flags); + } + else + { + u8 opcode = 0xb8 | to.Id; + xOpAccWrite(to.GetPrefix16(), opcode, 0, to); + xWrite64(imm); + } + } -const xImpl_MovImm64 xMOV64; + const xImpl_MovImm64 xMOV64; #endif -// -------------------------------------------------------------------------------------- -// CMOVcc -// -------------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------------- + // CMOVcc + // -------------------------------------------------------------------------------------- #define ccSane() pxAssertDev(ccType >= 0 && ccType <= 0x0f, "Invalid comparison type specifier.") @@ -169,63 +183,63 @@ const xImpl_MovImm64 xMOV64; -void xImpl_CMov::operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from) const -{ - pxAssert(to->GetOperandSize() == from->GetOperandSize()); - ccSane(); - xOpWrite0F(to->GetPrefix16(), 0x40 | ccType, to, from); -} + void xImpl_CMov::operator()(const xRegister16or32or64& to, const xRegister16or32or64& from) const + { + pxAssert(to->GetOperandSize() == from->GetOperandSize()); + ccSane(); + xOpWrite0F(to->GetPrefix16(), 0x40 | ccType, to, from); + } -void xImpl_CMov::operator()(const xRegister16or32or64 &to, const xIndirectVoid &sibsrc) const -{ - ccSane(); - xOpWrite0F(to->GetPrefix16(), 0x40 | ccType, to, sibsrc); -} + void xImpl_CMov::operator()(const xRegister16or32or64& to, const xIndirectVoid& sibsrc) const + { + ccSane(); + xOpWrite0F(to->GetPrefix16(), 0x40 | ccType, to, sibsrc); + } -//void xImpl_CMov::operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } -//void xImpl_CMov::operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } + //void xImpl_CMov::operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } + //void xImpl_CMov::operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } -void xImpl_Set::operator()(const xRegister8 &to) const -{ - ccSane(); - xOpWrite0F(0x90 | ccType, 0, to); -} -void xImpl_Set::operator()(const xIndirect8 &dest) const -{ - ccSane(); - xOpWrite0F(0x90 | ccType, 0, dest); -} -//void xImpl_Set::operator()( const xDirectOrIndirect8& dest ) const { ccSane(); _DoI_helpermess( *this, dest ); } + void xImpl_Set::operator()(const xRegister8& to) const + { + ccSane(); + xOpWrite0F(0x90 | ccType, 0, to); + } + void xImpl_Set::operator()(const xIndirect8& dest) const + { + ccSane(); + xOpWrite0F(0x90 | ccType, 0, dest); + } + //void xImpl_Set::operator()( const xDirectOrIndirect8& dest ) const { ccSane(); _DoI_helpermess( *this, dest ); } -void xImpl_MovExtend::operator()(const xRegister16or32or64 &to, const xRegister8 &from) const -{ - EbpAssert(); - xOpWrite0F( - (to->GetOperandSize() == 2) ? 0x66 : 0, - SignExtend ? 0xbe : 0xb6, - to, from); -} + void xImpl_MovExtend::operator()(const xRegister16or32or64& to, const xRegister8& from) const + { + EbpAssert(); + xOpWrite0F( + (to->GetOperandSize() == 2) ? 0x66 : 0, + SignExtend ? 0xbe : 0xb6, + to, from); + } -void xImpl_MovExtend::operator()(const xRegister16or32or64 &to, const xIndirect8 &sibsrc) const -{ - EbpAssert(); - xOpWrite0F( - (to->GetOperandSize() == 2) ? 0x66 : 0, - SignExtend ? 0xbe : 0xb6, - to, sibsrc); -} + void xImpl_MovExtend::operator()(const xRegister16or32or64& to, const xIndirect8& sibsrc) const + { + EbpAssert(); + xOpWrite0F( + (to->GetOperandSize() == 2) ? 0x66 : 0, + SignExtend ? 0xbe : 0xb6, + to, sibsrc); + } -void xImpl_MovExtend::operator()(const xRegister32or64 &to, const xRegister16 &from) const -{ - EbpAssert(); - xOpWrite0F(SignExtend ? 0xbf : 0xb7, to, from); -} + void xImpl_MovExtend::operator()(const xRegister32or64& to, const xRegister16& from) const + { + EbpAssert(); + xOpWrite0F(SignExtend ? 0xbf : 0xb7, to, from); + } -void xImpl_MovExtend::operator()(const xRegister32or64 &to, const xIndirect16 &sibsrc) const -{ - EbpAssert(); - xOpWrite0F(SignExtend ? 0xbf : 0xb7, to, sibsrc); -} + void xImpl_MovExtend::operator()(const xRegister32or64& to, const xIndirect16& sibsrc) const + { + EbpAssert(); + xOpWrite0F(SignExtend ? 0xbf : 0xb7, to, sibsrc); + } #if 0 void xImpl_MovExtend::operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const @@ -241,58 +255,58 @@ void xImpl_MovExtend::operator()( const xRegister16or32& to, const xDirectOrIndi } #endif -const xImpl_MovExtend xMOVSX = {true}; -const xImpl_MovExtend xMOVZX = {false}; + const xImpl_MovExtend xMOVSX = {true}; + const xImpl_MovExtend xMOVZX = {false}; -const xImpl_CMov xCMOVA = {Jcc_Above}; -const xImpl_CMov xCMOVAE = {Jcc_AboveOrEqual}; -const xImpl_CMov xCMOVB = {Jcc_Below}; -const xImpl_CMov xCMOVBE = {Jcc_BelowOrEqual}; + const xImpl_CMov xCMOVA = {Jcc_Above}; + const xImpl_CMov xCMOVAE = {Jcc_AboveOrEqual}; + const xImpl_CMov xCMOVB = {Jcc_Below}; + const xImpl_CMov xCMOVBE = {Jcc_BelowOrEqual}; -const xImpl_CMov xCMOVG = {Jcc_Greater}; -const xImpl_CMov xCMOVGE = {Jcc_GreaterOrEqual}; -const xImpl_CMov xCMOVL = {Jcc_Less}; -const xImpl_CMov xCMOVLE = {Jcc_LessOrEqual}; + const xImpl_CMov xCMOVG = {Jcc_Greater}; + const xImpl_CMov xCMOVGE = {Jcc_GreaterOrEqual}; + const xImpl_CMov xCMOVL = {Jcc_Less}; + const xImpl_CMov xCMOVLE = {Jcc_LessOrEqual}; -const xImpl_CMov xCMOVZ = {Jcc_Zero}; -const xImpl_CMov xCMOVE = {Jcc_Equal}; -const xImpl_CMov xCMOVNZ = {Jcc_NotZero}; -const xImpl_CMov xCMOVNE = {Jcc_NotEqual}; + const xImpl_CMov xCMOVZ = {Jcc_Zero}; + const xImpl_CMov xCMOVE = {Jcc_Equal}; + const xImpl_CMov xCMOVNZ = {Jcc_NotZero}; + const xImpl_CMov xCMOVNE = {Jcc_NotEqual}; -const xImpl_CMov xCMOVO = {Jcc_Overflow}; -const xImpl_CMov xCMOVNO = {Jcc_NotOverflow}; -const xImpl_CMov xCMOVC = {Jcc_Carry}; -const xImpl_CMov xCMOVNC = {Jcc_NotCarry}; + const xImpl_CMov xCMOVO = {Jcc_Overflow}; + const xImpl_CMov xCMOVNO = {Jcc_NotOverflow}; + const xImpl_CMov xCMOVC = {Jcc_Carry}; + const xImpl_CMov xCMOVNC = {Jcc_NotCarry}; -const xImpl_CMov xCMOVS = {Jcc_Signed}; -const xImpl_CMov xCMOVNS = {Jcc_Unsigned}; -const xImpl_CMov xCMOVPE = {Jcc_ParityEven}; -const xImpl_CMov xCMOVPO = {Jcc_ParityOdd}; + const xImpl_CMov xCMOVS = {Jcc_Signed}; + const xImpl_CMov xCMOVNS = {Jcc_Unsigned}; + const xImpl_CMov xCMOVPE = {Jcc_ParityEven}; + const xImpl_CMov xCMOVPO = {Jcc_ParityOdd}; -const xImpl_Set xSETA = {Jcc_Above}; -const xImpl_Set xSETAE = {Jcc_AboveOrEqual}; -const xImpl_Set xSETB = {Jcc_Below}; -const xImpl_Set xSETBE = {Jcc_BelowOrEqual}; + const xImpl_Set xSETA = {Jcc_Above}; + const xImpl_Set xSETAE = {Jcc_AboveOrEqual}; + const xImpl_Set xSETB = {Jcc_Below}; + const xImpl_Set xSETBE = {Jcc_BelowOrEqual}; -const xImpl_Set xSETG = {Jcc_Greater}; -const xImpl_Set xSETGE = {Jcc_GreaterOrEqual}; -const xImpl_Set xSETL = {Jcc_Less}; -const xImpl_Set xSETLE = {Jcc_LessOrEqual}; + const xImpl_Set xSETG = {Jcc_Greater}; + const xImpl_Set xSETGE = {Jcc_GreaterOrEqual}; + const xImpl_Set xSETL = {Jcc_Less}; + const xImpl_Set xSETLE = {Jcc_LessOrEqual}; -const xImpl_Set xSETZ = {Jcc_Zero}; -const xImpl_Set xSETE = {Jcc_Equal}; -const xImpl_Set xSETNZ = {Jcc_NotZero}; -const xImpl_Set xSETNE = {Jcc_NotEqual}; + const xImpl_Set xSETZ = {Jcc_Zero}; + const xImpl_Set xSETE = {Jcc_Equal}; + const xImpl_Set xSETNZ = {Jcc_NotZero}; + const xImpl_Set xSETNE = {Jcc_NotEqual}; -const xImpl_Set xSETO = {Jcc_Overflow}; -const xImpl_Set xSETNO = {Jcc_NotOverflow}; -const xImpl_Set xSETC = {Jcc_Carry}; -const xImpl_Set xSETNC = {Jcc_NotCarry}; + const xImpl_Set xSETO = {Jcc_Overflow}; + const xImpl_Set xSETNO = {Jcc_NotOverflow}; + const xImpl_Set xSETC = {Jcc_Carry}; + const xImpl_Set xSETNC = {Jcc_NotCarry}; -const xImpl_Set xSETS = {Jcc_Signed}; -const xImpl_Set xSETNS = {Jcc_Unsigned}; -const xImpl_Set xSETPE = {Jcc_ParityEven}; -const xImpl_Set xSETPO = {Jcc_ParityOdd}; + const xImpl_Set xSETS = {Jcc_Signed}; + const xImpl_Set xSETNS = {Jcc_Unsigned}; + const xImpl_Set xSETPE = {Jcc_ParityEven}; + const xImpl_Set xSETPO = {Jcc_ParityOdd}; } // end namespace x86Emitter diff --git a/common/emitter/simd.cpp b/common/emitter/simd.cpp index b115945478..197ca352b5 100644 --- a/common/emitter/simd.cpp +++ b/common/emitter/simd.cpp @@ -21,780 +21,787 @@ // AND'ing this mask against an MXCSR prior to LDMXCSR. SSE_MXCSR MXCSR_Mask; -const wxChar *EnumToString(SSE_RoundMode sse) +const wxChar* EnumToString(SSE_RoundMode sse) { - switch (sse) { - case SSEround_Nearest: - return L"Nearest"; - case SSEround_NegInf: - return L"NegativeInfinity"; - case SSEround_PosInf: - return L"PositiveInfinity"; - case SSEround_Chop: - return L"Chop"; - default: - return L"Invalid"; - } + switch (sse) + { + case SSEround_Nearest: + return L"Nearest"; + case SSEround_NegInf: + return L"NegativeInfinity"; + case SSEround_PosInf: + return L"PositiveInfinity"; + case SSEround_Chop: + return L"Chop"; + default: + return L"Invalid"; + } - return L"Invalid"; + return L"Invalid"; } SSE_RoundMode SSE_MXCSR::GetRoundMode() const { - return (SSE_RoundMode)RoundingControl; + return (SSE_RoundMode)RoundingControl; } -SSE_MXCSR &SSE_MXCSR::SetRoundMode(SSE_RoundMode mode) +SSE_MXCSR& SSE_MXCSR::SetRoundMode(SSE_RoundMode mode) { - pxAssert((uint)mode < 4); - RoundingControl = (u32)mode; - return *this; + pxAssert((uint)mode < 4); + RoundingControl = (u32)mode; + return *this; } -SSE_MXCSR &SSE_MXCSR::ClearExceptionFlags() +SSE_MXCSR& SSE_MXCSR::ClearExceptionFlags() { - bitmask &= ~0x3f; - return *this; + bitmask &= ~0x3f; + return *this; } -SSE_MXCSR &SSE_MXCSR::EnableExceptions() +SSE_MXCSR& SSE_MXCSR::EnableExceptions() { - bitmask &= ~(0x3f << 7); - return *this; + bitmask &= ~(0x3f << 7); + return *this; } -SSE_MXCSR &SSE_MXCSR::DisableExceptions() +SSE_MXCSR& SSE_MXCSR::DisableExceptions() { - bitmask |= 0x3f << 7; - return *this; + bitmask |= 0x3f << 7; + return *this; } // Applies the reserve bits mask for the current running cpu, as fetched from the CPU // during CPU init/detection. -SSE_MXCSR &SSE_MXCSR::ApplyReserveMask() +SSE_MXCSR& SSE_MXCSR::ApplyReserveMask() { - bitmask &= MXCSR_Mask.bitmask; - return *this; + bitmask &= MXCSR_Mask.bitmask; + return *this; } SSE_MXCSR::operator x86Emitter::xIndirect32() const { - return x86Emitter::ptr32[&bitmask]; + return x86Emitter::ptr32[&bitmask]; } namespace x86Emitter { -// ------------------------------------------------------------------------ -// SimdPrefix - If the lower byte of the opcode is 0x38 or 0x3a, then the opcode is -// treated as a 16 bit value (in SSE 0x38 and 0x3a denote prefixes for extended SSE3/4 -// instructions). Any other lower value assumes the upper value is 0 and ignored. -// Non-zero upper bytes, when the lower byte is not the 0x38 or 0x3a prefix, will -// generate an assertion. -// -__emitinline void SimdPrefix(u8 prefix, u16 opcode) -{ + // ------------------------------------------------------------------------ + // SimdPrefix - If the lower byte of the opcode is 0x38 or 0x3a, then the opcode is + // treated as a 16 bit value (in SSE 0x38 and 0x3a denote prefixes for extended SSE3/4 + // instructions). Any other lower value assumes the upper value is 0 and ignored. + // Non-zero upper bytes, when the lower byte is not the 0x38 or 0x3a prefix, will + // generate an assertion. + // + __emitinline void SimdPrefix(u8 prefix, u16 opcode) + { #ifdef __M_X86_64 - pxAssertMsg(prefix == 0, "REX prefix must be just before the opcode"); + pxAssertMsg(prefix == 0, "REX prefix must be just before the opcode"); #endif - const bool is16BitOpcode = ((opcode & 0xff) == 0x38) || ((opcode & 0xff) == 0x3a); - - // If the lower byte is not a valid prefix and the upper byte is non-zero it - // means we made a mistake! - if (!is16BitOpcode) - pxAssert((opcode >> 8) == 0); - - if (prefix != 0) { - if (is16BitOpcode) - xWrite32((opcode << 16) | 0x0f00 | prefix); - else { - xWrite16(0x0f00 | prefix); - xWrite8(opcode); - } - } else { - if (is16BitOpcode) { - xWrite8(0x0f); - xWrite16(opcode); - } else - xWrite16((opcode << 8) | 0x0f); - } -} - -const xImplSimd_DestRegEither xPAND = {0x66, 0xdb}; -const xImplSimd_DestRegEither xPANDN = {0x66, 0xdf}; -const xImplSimd_DestRegEither xPOR = {0x66, 0xeb}; -const xImplSimd_DestRegEither xPXOR = {0x66, 0xef}; - -// [SSE-4.1] Performs a bitwise AND of dest against src, and sets the ZF flag -// only if all bits in the result are 0. PTEST also sets the CF flag according -// to the following condition: (xmm2/m128 AND NOT xmm1) == 0; -const xImplSimd_DestRegSSE xPTEST = {0x66, 0x1738}; - -// ===================================================================================================== -// SSE Conversion Operations, as looney as they are. -// ===================================================================================================== -// These enforce pointer strictness for Indirect forms, due to the otherwise completely confusing -// nature of the functions. (so if a function expects an m32, you must use (u32*) or ptr32[]). -// - -__fi void xCVTDQ2PD(const xRegisterSSE &to, const xRegisterSSE &from) { OpWriteSSE(0xf3, 0xe6); } -__fi void xCVTDQ2PD(const xRegisterSSE &to, const xIndirect64 &from) { OpWriteSSE(0xf3, 0xe6); } -__fi void xCVTDQ2PS(const xRegisterSSE &to, const xRegisterSSE &from) { OpWriteSSE(0x00, 0x5b); } -__fi void xCVTDQ2PS(const xRegisterSSE &to, const xIndirect128 &from) { OpWriteSSE(0x00, 0x5b); } - -__fi void xCVTPD2DQ(const xRegisterSSE &to, const xRegisterSSE &from) { OpWriteSSE(0xf2, 0xe6); } -__fi void xCVTPD2DQ(const xRegisterSSE &to, const xIndirect128 &from) { OpWriteSSE(0xf2, 0xe6); } -__fi void xCVTPD2PS(const xRegisterSSE &to, const xRegisterSSE &from) { OpWriteSSE(0x66, 0x5a); } -__fi void xCVTPD2PS(const xRegisterSSE &to, const xIndirect128 &from) { OpWriteSSE(0x66, 0x5a); } - -__fi void xCVTPI2PD(const xRegisterSSE &to, const xIndirect64 &from) { OpWriteSSE(0x66, 0x2a); } -__fi void xCVTPI2PS(const xRegisterSSE &to, const xIndirect64 &from) { OpWriteSSE(0x00, 0x2a); } - -__fi void xCVTPS2DQ(const xRegisterSSE &to, const xRegisterSSE &from) { OpWriteSSE(0x66, 0x5b); } -__fi void xCVTPS2DQ(const xRegisterSSE &to, const xIndirect128 &from) { OpWriteSSE(0x66, 0x5b); } -__fi void xCVTPS2PD(const xRegisterSSE &to, const xRegisterSSE &from) { OpWriteSSE(0x00, 0x5a); } -__fi void xCVTPS2PD(const xRegisterSSE &to, const xIndirect64 &from) { OpWriteSSE(0x00, 0x5a); } - -__fi void xCVTSD2SI(const xRegister32or64 &to, const xRegisterSSE &from) { OpWriteSSE(0xf2, 0x2d); } -__fi void xCVTSD2SI(const xRegister32or64 &to, const xIndirect64 &from) { OpWriteSSE(0xf2, 0x2d); } -__fi void xCVTSD2SS(const xRegisterSSE &to, const xRegisterSSE &from) { OpWriteSSE(0xf2, 0x5a); } -__fi void xCVTSD2SS(const xRegisterSSE &to, const xIndirect64 &from) { OpWriteSSE(0xf2, 0x5a); } -__fi void xCVTSI2SS(const xRegisterSSE &to, const xRegister32or64 &from) { OpWriteSSE(0xf3, 0x2a); } -__fi void xCVTSI2SS(const xRegisterSSE &to, const xIndirect32 &from) { OpWriteSSE(0xf3, 0x2a); } - -__fi void xCVTSS2SD(const xRegisterSSE &to, const xRegisterSSE &from) { OpWriteSSE(0xf3, 0x5a); } -__fi void xCVTSS2SD(const xRegisterSSE &to, const xIndirect32 &from) { OpWriteSSE(0xf3, 0x5a); } -__fi void xCVTSS2SI(const xRegister32or64 &to, const xRegisterSSE &from) { OpWriteSSE(0xf3, 0x2d); } -__fi void xCVTSS2SI(const xRegister32or64 &to, const xIndirect32 &from) { OpWriteSSE(0xf3, 0x2d); } - -__fi void xCVTTPD2DQ(const xRegisterSSE &to, const xRegisterSSE &from) { OpWriteSSE(0x66, 0xe6); } -__fi void xCVTTPD2DQ(const xRegisterSSE &to, const xIndirect128 &from) { OpWriteSSE(0x66, 0xe6); } -__fi void xCVTTPS2DQ(const xRegisterSSE &to, const xRegisterSSE &from) { OpWriteSSE(0xf3, 0x5b); } -__fi void xCVTTPS2DQ(const xRegisterSSE &to, const xIndirect128 &from) { OpWriteSSE(0xf3, 0x5b); } - -__fi void xCVTTSD2SI(const xRegister32or64 &to, const xRegisterSSE &from) { OpWriteSSE(0xf2, 0x2c); } -__fi void xCVTTSD2SI(const xRegister32or64 &to, const xIndirect64 &from) { OpWriteSSE(0xf2, 0x2c); } -__fi void xCVTTSS2SI(const xRegister32or64 &to, const xRegisterSSE &from) { OpWriteSSE(0xf3, 0x2c); } -__fi void xCVTTSS2SI(const xRegister32or64 &to, const xIndirect32 &from) { OpWriteSSE(0xf3, 0x2c); } - - -// ------------------------------------------------------------------------ - -void xImplSimd_DestRegSSE::operator()(const xRegisterSSE &to, const xRegisterSSE &from) const { OpWriteSSE(Prefix, Opcode); } -void xImplSimd_DestRegSSE::operator()(const xRegisterSSE &to, const xIndirectVoid &from) const { OpWriteSSE(Prefix, Opcode); } - -void xImplSimd_DestRegImmSSE::operator()(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm) const { xOpWrite0F(Prefix, Opcode, to, from, imm); } -void xImplSimd_DestRegImmSSE::operator()(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm) const { xOpWrite0F(Prefix, Opcode, to, from, imm); } - - -void xImplSimd_DestRegEither::operator()(const xRegisterSSE &to, const xRegisterSSE &from) const { OpWriteSSE(Prefix, Opcode); } -void xImplSimd_DestRegEither::operator()(const xRegisterSSE &to, const xIndirectVoid &from) const { OpWriteSSE(Prefix, Opcode); } - - -void xImplSimd_DestSSE_CmpImm::operator()(const xRegisterSSE &to, const xRegisterSSE &from, SSE2_ComparisonType imm) const { xOpWrite0F(Prefix, Opcode, to, from, imm); } -void xImplSimd_DestSSE_CmpImm::operator()(const xRegisterSSE &to, const xIndirectVoid &from, SSE2_ComparisonType imm) const { xOpWrite0F(Prefix, Opcode, to, from, imm); } - -// ===================================================================================================== -// SIMD Arithmetic Instructions -// ===================================================================================================== - -void _SimdShiftHelper::operator()(const xRegisterSSE &to, const xRegisterSSE &from) const { OpWriteSSE(Prefix, Opcode); } -void _SimdShiftHelper::operator()(const xRegisterSSE &to, const xIndirectVoid &from) const { OpWriteSSE(Prefix, Opcode); } - - -void _SimdShiftHelper::operator()(const xRegisterSSE &to, u8 imm8) const -{ - xOpWrite0F(0x66, OpcodeImm, (int)Modcode, to); - xWrite8(imm8); -} - -void xImplSimd_Shift::DQ(const xRegisterSSE &to, u8 imm8) const -{ - xOpWrite0F(0x66, 0x73, (int)Q.Modcode + 1, to, imm8); -} - - -const xImplSimd_ShiftWithoutQ xPSRA = - { - {0x66, 0xe1, 0x71, 4}, // W - {0x66, 0xe2, 0x72, 4} // D -}; - -const xImplSimd_Shift xPSRL = - { - {0x66, 0xd1, 0x71, 2}, // W - {0x66, 0xd2, 0x72, 2}, // D - {0x66, 0xd3, 0x73, 2}, // Q -}; - -const xImplSimd_Shift xPSLL = - { - {0x66, 0xf1, 0x71, 6}, // W - {0x66, 0xf2, 0x72, 6}, // D - {0x66, 0xf3, 0x73, 6}, // Q -}; - -const xImplSimd_AddSub xPADD = - { - {0x66, 0xdc + 0x20}, // B - {0x66, 0xdc + 0x21}, // W - {0x66, 0xdc + 0x22}, // D - {0x66, 0xd4}, // Q - - {0x66, 0xdc + 0x10}, // SB - {0x66, 0xdc + 0x11}, // SW - {0x66, 0xdc}, // USB - {0x66, 0xdc + 1}, // USW -}; - -const xImplSimd_AddSub xPSUB = - { - {0x66, 0xd8 + 0x20}, // B - {0x66, 0xd8 + 0x21}, // W - {0x66, 0xd8 + 0x22}, // D - {0x66, 0xfb}, // Q - - {0x66, 0xd8 + 0x10}, // SB - {0x66, 0xd8 + 0x11}, // SW - {0x66, 0xd8}, // USB - {0x66, 0xd8 + 1}, // USW -}; - -const xImplSimd_PMul xPMUL = - { - {0x66, 0xd5}, // LW - {0x66, 0xe5}, // HW - {0x66, 0xe4}, // HUW - {0x66, 0xf4}, // UDQ - - {0x66, 0x0b38}, // HRSW - {0x66, 0x4038}, // LD - {0x66, 0x2838}, // DQ -}; - -const xImplSimd_rSqrt xRSQRT = - { - {0x00, 0x52}, // PS - {0xf3, 0x52} // SS -}; - -const xImplSimd_rSqrt xRCP = - { - {0x00, 0x53}, // PS - {0xf3, 0x53} // SS -}; - -const xImplSimd_Sqrt xSQRT = - { - {0x00, 0x51}, // PS - {0xf3, 0x51}, // SS - {0xf2, 0x51} // SS -}; - -const xImplSimd_AndNot xANDN = - { - {0x00, 0x55}, // PS - {0x66, 0x55} // PD -}; - -const xImplSimd_PAbsolute xPABS = - { - {0x66, 0x1c38}, // B - {0x66, 0x1d38}, // W - {0x66, 0x1e38} // D -}; - -const xImplSimd_PSign xPSIGN = - { - {0x66, 0x0838}, // B - {0x66, 0x0938}, // W - {0x66, 0x0a38}, // D -}; - -const xImplSimd_PMultAdd xPMADD = - { - {0x66, 0xf5}, // WD - {0x66, 0xf438}, // UBSW -}; - -const xImplSimd_HorizAdd xHADD = - { - {0xf2, 0x7c}, // PS - {0x66, 0x7c}, // PD -}; - -const xImplSimd_DotProduct xDP = - { - {0x66, 0x403a}, // PS - {0x66, 0x413a}, // PD -}; - -const xImplSimd_Round xROUND = - { - {0x66, 0x083a}, // PS - {0x66, 0x093a}, // PD - {0x66, 0x0a3a}, // SS - {0x66, 0x0b3a}, // SD -}; - -// ===================================================================================================== -// SIMD Comparison Instructions -// ===================================================================================================== - -void xImplSimd_Compare::PS(const xRegisterSSE &to, const xRegisterSSE &from) const { xOpWrite0F(0x00, 0xc2, to, from, (u8)CType); } -void xImplSimd_Compare::PS(const xRegisterSSE &to, const xIndirectVoid &from) const { xOpWrite0F(0x00, 0xc2, to, from, (u8)CType); } - -void xImplSimd_Compare::PD(const xRegisterSSE &to, const xRegisterSSE &from) const { xOpWrite0F(0x66, 0xc2, to, from, (u8)CType); } -void xImplSimd_Compare::PD(const xRegisterSSE &to, const xIndirectVoid &from) const { xOpWrite0F(0x66, 0xc2, to, from, (u8)CType); } - -void xImplSimd_Compare::SS(const xRegisterSSE &to, const xRegisterSSE &from) const { xOpWrite0F(0xf3, 0xc2, to, from, (u8)CType); } -void xImplSimd_Compare::SS(const xRegisterSSE &to, const xIndirectVoid &from) const { xOpWrite0F(0xf3, 0xc2, to, from, (u8)CType); } - -void xImplSimd_Compare::SD(const xRegisterSSE &to, const xRegisterSSE &from) const { xOpWrite0F(0xf2, 0xc2, to, from, (u8)CType); } -void xImplSimd_Compare::SD(const xRegisterSSE &to, const xIndirectVoid &from) const { xOpWrite0F(0xf2, 0xc2, to, from, (u8)CType); } - -const xImplSimd_MinMax xMIN = - { - {0x00, 0x5d}, // PS - {0x66, 0x5d}, // PD - {0xf3, 0x5d}, // SS - {0xf2, 0x5d}, // SD -}; - -const xImplSimd_MinMax xMAX = - { - {0x00, 0x5f}, // PS - {0x66, 0x5f}, // PD - {0xf3, 0x5f}, // SS - {0xf2, 0x5f}, // SD -}; - -// [TODO] : Merge this into the xCMP class, so that they are notation as: xCMP.EQ - -const xImplSimd_Compare xCMPEQ = {SSE2_Equal}; -const xImplSimd_Compare xCMPLT = {SSE2_Less}; -const xImplSimd_Compare xCMPLE = {SSE2_LessOrEqual}; -const xImplSimd_Compare xCMPUNORD = {SSE2_LessOrEqual}; -const xImplSimd_Compare xCMPNE = {SSE2_NotEqual}; -const xImplSimd_Compare xCMPNLT = {SSE2_NotLess}; -const xImplSimd_Compare xCMPNLE = {SSE2_NotLessOrEqual}; -const xImplSimd_Compare xCMPORD = {SSE2_Ordered}; - -const xImplSimd_COMI xCOMI = - { - {0x00, 0x2f}, // SS - {0x66, 0x2f}, // SD -}; - -const xImplSimd_COMI xUCOMI = - { - {0x00, 0x2e}, // SS - {0x66, 0x2e}, // SD -}; - -const xImplSimd_PCompare xPCMP = - { - {0x66, 0x74}, // EQB - {0x66, 0x75}, // EQW - {0x66, 0x76}, // EQD - - {0x66, 0x64}, // GTB - {0x66, 0x65}, // GTW - {0x66, 0x66}, // GTD -}; - -const xImplSimd_PMinMax xPMIN = - { - {0x66, 0xda}, // UB - {0x66, 0xea}, // SW - {0x66, 0x3838}, // SB - {0x66, 0x3938}, // SD - - {0x66, 0x3a38}, // UW - {0x66, 0x3b38}, // UD -}; - -const xImplSimd_PMinMax xPMAX = - { - {0x66, 0xde}, // UB - {0x66, 0xee}, // SW - {0x66, 0x3c38}, // SB - {0x66, 0x3d38}, // SD - - {0x66, 0x3e38}, // UW - {0x66, 0x3f38}, // UD -}; - -// ===================================================================================================== -// SIMD Shuffle/Pack (Shuffle puck?) -// ===================================================================================================== - -__fi void xImplSimd_Shuffle::_selector_assertion_check(u8 selector) const -{ - pxAssertMsg((selector & ~3) == 0, - "Invalid immediate operand on SSE Shuffle: Upper 6 bits of the SSE Shuffle-PD Selector are reserved and must be zero."); -} - -void xImplSimd_Shuffle::PS(const xRegisterSSE &to, const xRegisterSSE &from, u8 selector) const -{ - xOpWrite0F(0xc6, to, from, selector); -} - -void xImplSimd_Shuffle::PS(const xRegisterSSE &to, const xIndirectVoid &from, u8 selector) const -{ - xOpWrite0F(0xc6, to, from, selector); -} - -void xImplSimd_Shuffle::PD(const xRegisterSSE &to, const xRegisterSSE &from, u8 selector) const -{ - _selector_assertion_check(selector); - xOpWrite0F(0x66, 0xc6, to, from, selector & 0x3); -} - -void xImplSimd_Shuffle::PD(const xRegisterSSE &to, const xIndirectVoid &from, u8 selector) const -{ - _selector_assertion_check(selector); - xOpWrite0F(0x66, 0xc6, to, from, selector & 0x3); -} - -void xImplSimd_InsertExtractHelper::operator()(const xRegisterSSE &to, const xRegister32 &from, u8 imm8) const -{ - xOpWrite0F(0x66, Opcode, to, from, imm8); -} - -void xImplSimd_InsertExtractHelper::operator()(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm8) const -{ - xOpWrite0F(0x66, Opcode, to, from, imm8); -} - -void xImplSimd_PInsert::W(const xRegisterSSE &to, const xRegister32 &from, u8 imm8) const { xOpWrite0F(0x66, 0xc4, to, from, imm8); } -void xImplSimd_PInsert::W(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm8) const { xOpWrite0F(0x66, 0xc4, to, from, imm8); } - -void SimdImpl_PExtract::W(const xRegister32 &to, const xRegisterSSE &from, u8 imm8) const { xOpWrite0F(0x66, 0xc5, to, from, imm8); } -void SimdImpl_PExtract::W(const xIndirectVoid &dest, const xRegisterSSE &from, u8 imm8) const { xOpWrite0F(0x66, 0x153a, from, dest, imm8); } - -const xImplSimd_Shuffle xSHUF = {}; - -const xImplSimd_PShuffle xPSHUF = - { - {0x66, 0x70}, // D - {0xf2, 0x70}, // LW - {0xf3, 0x70}, // HW - - {0x66, 0x0038}, // B -}; - -const SimdImpl_PUnpack xPUNPCK = - { - {0x66, 0x60}, // LBW - {0x66, 0x61}, // LWD - {0x66, 0x62}, // LDQ - {0x66, 0x6c}, // LQDQ - - {0x66, 0x68}, // HBW - {0x66, 0x69}, // HWD - {0x66, 0x6a}, // HDQ - {0x66, 0x6d}, // HQDQ -}; - -const SimdImpl_Pack xPACK = - { - {0x66, 0x63}, // SSWB - {0x66, 0x6b}, // SSDW - {0x66, 0x67}, // USWB - {0x66, 0x2b38}, // USDW -}; - -const xImplSimd_Unpack xUNPCK = - { - {0x00, 0x15}, // HPS - {0x66, 0x15}, // HPD - {0x00, 0x14}, // LPS - {0x66, 0x14}, // LPD -}; - -const xImplSimd_PInsert xPINSR = - { - {0x203a}, // B - {0x223a}, // D -}; - -const SimdImpl_PExtract xPEXTR = - { - {0x143a}, // B - {0x163a}, // D -}; - -// ===================================================================================================== -// SIMD Move And Blend Instructions -// ===================================================================================================== - -void xImplSimd_MovHL::PS(const xRegisterSSE &to, const xIndirectVoid &from) const { xOpWrite0F(Opcode, to, from); } -void xImplSimd_MovHL::PS(const xIndirectVoid &to, const xRegisterSSE &from) const { xOpWrite0F(Opcode + 1, from, to); } - -void xImplSimd_MovHL::PD(const xRegisterSSE &to, const xIndirectVoid &from) const { xOpWrite0F(0x66, Opcode, to, from); } -void xImplSimd_MovHL::PD(const xIndirectVoid &to, const xRegisterSSE &from) const { xOpWrite0F(0x66, Opcode + 1, from, to); } - -void xImplSimd_MovHL_RtoR::PS(const xRegisterSSE &to, const xRegisterSSE &from) const { xOpWrite0F(Opcode, to, from); } -void xImplSimd_MovHL_RtoR::PD(const xRegisterSSE &to, const xRegisterSSE &from) const { xOpWrite0F(0x66, Opcode, to, from); } - -static const u16 MovPS_OpAligned = 0x28; // Aligned [aps] form -static const u16 MovPS_OpUnaligned = 0x10; // unaligned [ups] form - -void xImplSimd_MoveSSE::operator()(const xRegisterSSE &to, const xRegisterSSE &from) const -{ - if (to != from) - xOpWrite0F(Prefix, MovPS_OpAligned, to, from); -} - -void xImplSimd_MoveSSE::operator()(const xRegisterSSE &to, const xIndirectVoid &from) const -{ - // ModSib form is aligned if it's displacement-only and the displacement is aligned: - bool isReallyAligned = isAligned || (((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty()); - - xOpWrite0F(Prefix, isReallyAligned ? MovPS_OpAligned : MovPS_OpUnaligned, to, from); -} - -void xImplSimd_MoveSSE::operator()(const xIndirectVoid &to, const xRegisterSSE &from) const -{ - // ModSib form is aligned if it's displacement-only and the displacement is aligned: - bool isReallyAligned = isAligned || ((to.Displacement & 0x0f) == 0 && to.Index.IsEmpty() && to.Base.IsEmpty()); - xOpWrite0F(Prefix, isReallyAligned ? MovPS_OpAligned + 1 : MovPS_OpUnaligned + 1, from, to); -} - -static const u8 MovDQ_PrefixAligned = 0x66; // Aligned [dqa] form -static const u8 MovDQ_PrefixUnaligned = 0xf3; // unaligned [dqu] form - -void xImplSimd_MoveDQ::operator()(const xRegisterSSE &to, const xRegisterSSE &from) const -{ - if (to != from) - xOpWrite0F(MovDQ_PrefixAligned, 0x6f, to, from); -} - -void xImplSimd_MoveDQ::operator()(const xRegisterSSE &to, const xIndirectVoid &from) const -{ - // ModSib form is aligned if it's displacement-only and the displacement is aligned: - bool isReallyAligned = isAligned || ((from.Displacement & 0x0f) == 0 && from.Index.IsEmpty() && from.Base.IsEmpty()); - xOpWrite0F(isReallyAligned ? MovDQ_PrefixAligned : MovDQ_PrefixUnaligned, 0x6f, to, from); -} - -void xImplSimd_MoveDQ::operator()(const xIndirectVoid &to, const xRegisterSSE &from) const -{ - // ModSib form is aligned if it's displacement-only and the displacement is aligned: - bool isReallyAligned = isAligned || ((to.Displacement & 0x0f) == 0 && to.Index.IsEmpty() && to.Base.IsEmpty()); - - // use opcode 0x7f : alternate ModRM encoding (reverse src/dst) - xOpWrite0F(isReallyAligned ? MovDQ_PrefixAligned : MovDQ_PrefixUnaligned, 0x7f, from, to); -} - -void xImplSimd_PMove::BW(const xRegisterSSE &to, const xRegisterSSE &from) const { OpWriteSSE(0x66, OpcodeBase); } -void xImplSimd_PMove::BW(const xRegisterSSE &to, const xIndirect64 &from) const { OpWriteSSE(0x66, OpcodeBase); } - -void xImplSimd_PMove::BD(const xRegisterSSE &to, const xRegisterSSE &from) const { OpWriteSSE(0x66, OpcodeBase + 0x100); } -void xImplSimd_PMove::BD(const xRegisterSSE &to, const xIndirect32 &from) const { OpWriteSSE(0x66, OpcodeBase + 0x100); } - -void xImplSimd_PMove::BQ(const xRegisterSSE &to, const xRegisterSSE &from) const { OpWriteSSE(0x66, OpcodeBase + 0x200); } -void xImplSimd_PMove::BQ(const xRegisterSSE &to, const xIndirect16 &from) const { OpWriteSSE(0x66, OpcodeBase + 0x200); } - -void xImplSimd_PMove::WD(const xRegisterSSE &to, const xRegisterSSE &from) const { OpWriteSSE(0x66, OpcodeBase + 0x300); } -void xImplSimd_PMove::WD(const xRegisterSSE &to, const xIndirect64 &from) const { OpWriteSSE(0x66, OpcodeBase + 0x300); } - -void xImplSimd_PMove::WQ(const xRegisterSSE &to, const xRegisterSSE &from) const { OpWriteSSE(0x66, OpcodeBase + 0x400); } -void xImplSimd_PMove::WQ(const xRegisterSSE &to, const xIndirect32 &from) const { OpWriteSSE(0x66, OpcodeBase + 0x400); } - -void xImplSimd_PMove::DQ(const xRegisterSSE &to, const xRegisterSSE &from) const { OpWriteSSE(0x66, OpcodeBase + 0x500); } -void xImplSimd_PMove::DQ(const xRegisterSSE &to, const xIndirect64 &from) const { OpWriteSSE(0x66, OpcodeBase + 0x500); } - - -const xImplSimd_MoveSSE xMOVAPS = {0x00, true}; -const xImplSimd_MoveSSE xMOVUPS = {0x00, false}; + const bool is16BitOpcode = ((opcode & 0xff) == 0x38) || ((opcode & 0xff) == 0x3a); + + // If the lower byte is not a valid prefix and the upper byte is non-zero it + // means we made a mistake! + if (!is16BitOpcode) + pxAssert((opcode >> 8) == 0); + + if (prefix != 0) + { + if (is16BitOpcode) + xWrite32((opcode << 16) | 0x0f00 | prefix); + else + { + xWrite16(0x0f00 | prefix); + xWrite8(opcode); + } + } + else + { + if (is16BitOpcode) + { + xWrite8(0x0f); + xWrite16(opcode); + } + else + xWrite16((opcode << 8) | 0x0f); + } + } + + const xImplSimd_DestRegEither xPAND = {0x66, 0xdb}; + const xImplSimd_DestRegEither xPANDN = {0x66, 0xdf}; + const xImplSimd_DestRegEither xPOR = {0x66, 0xeb}; + const xImplSimd_DestRegEither xPXOR = {0x66, 0xef}; + + // [SSE-4.1] Performs a bitwise AND of dest against src, and sets the ZF flag + // only if all bits in the result are 0. PTEST also sets the CF flag according + // to the following condition: (xmm2/m128 AND NOT xmm1) == 0; + const xImplSimd_DestRegSSE xPTEST = {0x66, 0x1738}; + + // ===================================================================================================== + // SSE Conversion Operations, as looney as they are. + // ===================================================================================================== + // These enforce pointer strictness for Indirect forms, due to the otherwise completely confusing + // nature of the functions. (so if a function expects an m32, you must use (u32*) or ptr32[]). + // + + __fi void xCVTDQ2PD(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0xf3, 0xe6); } + __fi void xCVTDQ2PD(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSSE(0xf3, 0xe6); } + __fi void xCVTDQ2PS(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0x00, 0x5b); } + __fi void xCVTDQ2PS(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0x00, 0x5b); } + + __fi void xCVTPD2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0xf2, 0xe6); } + __fi void xCVTPD2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0xf2, 0xe6); } + __fi void xCVTPD2PS(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0x66, 0x5a); } + __fi void xCVTPD2PS(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0x66, 0x5a); } + + __fi void xCVTPI2PD(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSSE(0x66, 0x2a); } + __fi void xCVTPI2PS(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSSE(0x00, 0x2a); } + + __fi void xCVTPS2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0x66, 0x5b); } + __fi void xCVTPS2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0x66, 0x5b); } + __fi void xCVTPS2PD(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0x00, 0x5a); } + __fi void xCVTPS2PD(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSSE(0x00, 0x5a); } + + __fi void xCVTSD2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSSE(0xf2, 0x2d); } + __fi void xCVTSD2SI(const xRegister32or64& to, const xIndirect64& from) { OpWriteSSE(0xf2, 0x2d); } + __fi void xCVTSD2SS(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0xf2, 0x5a); } + __fi void xCVTSD2SS(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSSE(0xf2, 0x5a); } + __fi void xCVTSI2SS(const xRegisterSSE& to, const xRegister32or64& from) { OpWriteSSE(0xf3, 0x2a); } + __fi void xCVTSI2SS(const xRegisterSSE& to, const xIndirect32& from) { OpWriteSSE(0xf3, 0x2a); } + + __fi void xCVTSS2SD(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0xf3, 0x5a); } + __fi void xCVTSS2SD(const xRegisterSSE& to, const xIndirect32& from) { OpWriteSSE(0xf3, 0x5a); } + __fi void xCVTSS2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSSE(0xf3, 0x2d); } + __fi void xCVTSS2SI(const xRegister32or64& to, const xIndirect32& from) { OpWriteSSE(0xf3, 0x2d); } + + __fi void xCVTTPD2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0x66, 0xe6); } + __fi void xCVTTPD2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0x66, 0xe6); } + __fi void xCVTTPS2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0xf3, 0x5b); } + __fi void xCVTTPS2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0xf3, 0x5b); } + + __fi void xCVTTSD2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSSE(0xf2, 0x2c); } + __fi void xCVTTSD2SI(const xRegister32or64& to, const xIndirect64& from) { OpWriteSSE(0xf2, 0x2c); } + __fi void xCVTTSS2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSSE(0xf3, 0x2c); } + __fi void xCVTTSS2SI(const xRegister32or64& to, const xIndirect32& from) { OpWriteSSE(0xf3, 0x2c); } + + + // ------------------------------------------------------------------------ + + void xImplSimd_DestRegSSE::operator()(const xRegisterSSE& to, const xRegisterSSE& from) const { OpWriteSSE(Prefix, Opcode); } + void xImplSimd_DestRegSSE::operator()(const xRegisterSSE& to, const xIndirectVoid& from) const { OpWriteSSE(Prefix, Opcode); } + + void xImplSimd_DestRegImmSSE::operator()(const xRegisterSSE& to, const xRegisterSSE& from, u8 imm) const { xOpWrite0F(Prefix, Opcode, to, from, imm); } + void xImplSimd_DestRegImmSSE::operator()(const xRegisterSSE& to, const xIndirectVoid& from, u8 imm) const { xOpWrite0F(Prefix, Opcode, to, from, imm); } + + + void xImplSimd_DestRegEither::operator()(const xRegisterSSE& to, const xRegisterSSE& from) const { OpWriteSSE(Prefix, Opcode); } + void xImplSimd_DestRegEither::operator()(const xRegisterSSE& to, const xIndirectVoid& from) const { OpWriteSSE(Prefix, Opcode); } + + + void xImplSimd_DestSSE_CmpImm::operator()(const xRegisterSSE& to, const xRegisterSSE& from, SSE2_ComparisonType imm) const { xOpWrite0F(Prefix, Opcode, to, from, imm); } + void xImplSimd_DestSSE_CmpImm::operator()(const xRegisterSSE& to, const xIndirectVoid& from, SSE2_ComparisonType imm) const { xOpWrite0F(Prefix, Opcode, to, from, imm); } + + // ===================================================================================================== + // SIMD Arithmetic Instructions + // ===================================================================================================== + + void _SimdShiftHelper::operator()(const xRegisterSSE& to, const xRegisterSSE& from) const { OpWriteSSE(Prefix, Opcode); } + void _SimdShiftHelper::operator()(const xRegisterSSE& to, const xIndirectVoid& from) const { OpWriteSSE(Prefix, Opcode); } + + + void _SimdShiftHelper::operator()(const xRegisterSSE& to, u8 imm8) const + { + xOpWrite0F(0x66, OpcodeImm, (int)Modcode, to); + xWrite8(imm8); + } + + void xImplSimd_Shift::DQ(const xRegisterSSE& to, u8 imm8) const + { + xOpWrite0F(0x66, 0x73, (int)Q.Modcode + 1, to, imm8); + } + + + const xImplSimd_ShiftWithoutQ xPSRA = + { + {0x66, 0xe1, 0x71, 4}, // W + {0x66, 0xe2, 0x72, 4} // D + }; + + const xImplSimd_Shift xPSRL = + { + {0x66, 0xd1, 0x71, 2}, // W + {0x66, 0xd2, 0x72, 2}, // D + {0x66, 0xd3, 0x73, 2}, // Q + }; + + const xImplSimd_Shift xPSLL = + { + {0x66, 0xf1, 0x71, 6}, // W + {0x66, 0xf2, 0x72, 6}, // D + {0x66, 0xf3, 0x73, 6}, // Q + }; + + const xImplSimd_AddSub xPADD = + { + {0x66, 0xdc + 0x20}, // B + {0x66, 0xdc + 0x21}, // W + {0x66, 0xdc + 0x22}, // D + {0x66, 0xd4}, // Q + + {0x66, 0xdc + 0x10}, // SB + {0x66, 0xdc + 0x11}, // SW + {0x66, 0xdc}, // USB + {0x66, 0xdc + 1}, // USW + }; + + const xImplSimd_AddSub xPSUB = + { + {0x66, 0xd8 + 0x20}, // B + {0x66, 0xd8 + 0x21}, // W + {0x66, 0xd8 + 0x22}, // D + {0x66, 0xfb}, // Q + + {0x66, 0xd8 + 0x10}, // SB + {0x66, 0xd8 + 0x11}, // SW + {0x66, 0xd8}, // USB + {0x66, 0xd8 + 1}, // USW + }; + + const xImplSimd_PMul xPMUL = + { + {0x66, 0xd5}, // LW + {0x66, 0xe5}, // HW + {0x66, 0xe4}, // HUW + {0x66, 0xf4}, // UDQ + + {0x66, 0x0b38}, // HRSW + {0x66, 0x4038}, // LD + {0x66, 0x2838}, // DQ + }; + + const xImplSimd_rSqrt xRSQRT = + { + {0x00, 0x52}, // PS + {0xf3, 0x52} // SS + }; + + const xImplSimd_rSqrt xRCP = + { + {0x00, 0x53}, // PS + {0xf3, 0x53} // SS + }; + + const xImplSimd_Sqrt xSQRT = + { + {0x00, 0x51}, // PS + {0xf3, 0x51}, // SS + {0xf2, 0x51} // SS + }; + + const xImplSimd_AndNot xANDN = + { + {0x00, 0x55}, // PS + {0x66, 0x55} // PD + }; + + const xImplSimd_PAbsolute xPABS = + { + {0x66, 0x1c38}, // B + {0x66, 0x1d38}, // W + {0x66, 0x1e38} // D + }; + + const xImplSimd_PSign xPSIGN = + { + {0x66, 0x0838}, // B + {0x66, 0x0938}, // W + {0x66, 0x0a38}, // D + }; + + const xImplSimd_PMultAdd xPMADD = + { + {0x66, 0xf5}, // WD + {0x66, 0xf438}, // UBSW + }; + + const xImplSimd_HorizAdd xHADD = + { + {0xf2, 0x7c}, // PS + {0x66, 0x7c}, // PD + }; + + const xImplSimd_DotProduct xDP = + { + {0x66, 0x403a}, // PS + {0x66, 0x413a}, // PD + }; + + const xImplSimd_Round xROUND = + { + {0x66, 0x083a}, // PS + {0x66, 0x093a}, // PD + {0x66, 0x0a3a}, // SS + {0x66, 0x0b3a}, // SD + }; + + // ===================================================================================================== + // SIMD Comparison Instructions + // ===================================================================================================== + + void xImplSimd_Compare::PS(const xRegisterSSE& to, const xRegisterSSE& from) const { xOpWrite0F(0x00, 0xc2, to, from, (u8)CType); } + void xImplSimd_Compare::PS(const xRegisterSSE& to, const xIndirectVoid& from) const { xOpWrite0F(0x00, 0xc2, to, from, (u8)CType); } + + void xImplSimd_Compare::PD(const xRegisterSSE& to, const xRegisterSSE& from) const { xOpWrite0F(0x66, 0xc2, to, from, (u8)CType); } + void xImplSimd_Compare::PD(const xRegisterSSE& to, const xIndirectVoid& from) const { xOpWrite0F(0x66, 0xc2, to, from, (u8)CType); } + + void xImplSimd_Compare::SS(const xRegisterSSE& to, const xRegisterSSE& from) const { xOpWrite0F(0xf3, 0xc2, to, from, (u8)CType); } + void xImplSimd_Compare::SS(const xRegisterSSE& to, const xIndirectVoid& from) const { xOpWrite0F(0xf3, 0xc2, to, from, (u8)CType); } + + void xImplSimd_Compare::SD(const xRegisterSSE& to, const xRegisterSSE& from) const { xOpWrite0F(0xf2, 0xc2, to, from, (u8)CType); } + void xImplSimd_Compare::SD(const xRegisterSSE& to, const xIndirectVoid& from) const { xOpWrite0F(0xf2, 0xc2, to, from, (u8)CType); } + + const xImplSimd_MinMax xMIN = + { + {0x00, 0x5d}, // PS + {0x66, 0x5d}, // PD + {0xf3, 0x5d}, // SS + {0xf2, 0x5d}, // SD + }; + + const xImplSimd_MinMax xMAX = + { + {0x00, 0x5f}, // PS + {0x66, 0x5f}, // PD + {0xf3, 0x5f}, // SS + {0xf2, 0x5f}, // SD + }; + + // [TODO] : Merge this into the xCMP class, so that they are notation as: xCMP.EQ + + const xImplSimd_Compare xCMPEQ = {SSE2_Equal}; + const xImplSimd_Compare xCMPLT = {SSE2_Less}; + const xImplSimd_Compare xCMPLE = {SSE2_LessOrEqual}; + const xImplSimd_Compare xCMPUNORD = {SSE2_LessOrEqual}; + const xImplSimd_Compare xCMPNE = {SSE2_NotEqual}; + const xImplSimd_Compare xCMPNLT = {SSE2_NotLess}; + const xImplSimd_Compare xCMPNLE = {SSE2_NotLessOrEqual}; + const xImplSimd_Compare xCMPORD = {SSE2_Ordered}; + + const xImplSimd_COMI xCOMI = + { + {0x00, 0x2f}, // SS + {0x66, 0x2f}, // SD + }; + + const xImplSimd_COMI xUCOMI = + { + {0x00, 0x2e}, // SS + {0x66, 0x2e}, // SD + }; + + const xImplSimd_PCompare xPCMP = + { + {0x66, 0x74}, // EQB + {0x66, 0x75}, // EQW + {0x66, 0x76}, // EQD + + {0x66, 0x64}, // GTB + {0x66, 0x65}, // GTW + {0x66, 0x66}, // GTD + }; + + const xImplSimd_PMinMax xPMIN = + { + {0x66, 0xda}, // UB + {0x66, 0xea}, // SW + {0x66, 0x3838}, // SB + {0x66, 0x3938}, // SD + + {0x66, 0x3a38}, // UW + {0x66, 0x3b38}, // UD + }; + + const xImplSimd_PMinMax xPMAX = + { + {0x66, 0xde}, // UB + {0x66, 0xee}, // SW + {0x66, 0x3c38}, // SB + {0x66, 0x3d38}, // SD + + {0x66, 0x3e38}, // UW + {0x66, 0x3f38}, // UD + }; + + // ===================================================================================================== + // SIMD Shuffle/Pack (Shuffle puck?) + // ===================================================================================================== + + __fi void xImplSimd_Shuffle::_selector_assertion_check(u8 selector) const + { + pxAssertMsg((selector & ~3) == 0, + "Invalid immediate operand on SSE Shuffle: Upper 6 bits of the SSE Shuffle-PD Selector are reserved and must be zero."); + } + + void xImplSimd_Shuffle::PS(const xRegisterSSE& to, const xRegisterSSE& from, u8 selector) const + { + xOpWrite0F(0xc6, to, from, selector); + } + + void xImplSimd_Shuffle::PS(const xRegisterSSE& to, const xIndirectVoid& from, u8 selector) const + { + xOpWrite0F(0xc6, to, from, selector); + } + + void xImplSimd_Shuffle::PD(const xRegisterSSE& to, const xRegisterSSE& from, u8 selector) const + { + _selector_assertion_check(selector); + xOpWrite0F(0x66, 0xc6, to, from, selector & 0x3); + } + + void xImplSimd_Shuffle::PD(const xRegisterSSE& to, const xIndirectVoid& from, u8 selector) const + { + _selector_assertion_check(selector); + xOpWrite0F(0x66, 0xc6, to, from, selector & 0x3); + } + + void xImplSimd_InsertExtractHelper::operator()(const xRegisterSSE& to, const xRegister32& from, u8 imm8) const + { + xOpWrite0F(0x66, Opcode, to, from, imm8); + } + + void xImplSimd_InsertExtractHelper::operator()(const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8) const + { + xOpWrite0F(0x66, Opcode, to, from, imm8); + } + + void xImplSimd_PInsert::W(const xRegisterSSE& to, const xRegister32& from, u8 imm8) const { xOpWrite0F(0x66, 0xc4, to, from, imm8); } + void xImplSimd_PInsert::W(const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8) const { xOpWrite0F(0x66, 0xc4, to, from, imm8); } + + void SimdImpl_PExtract::W(const xRegister32& to, const xRegisterSSE& from, u8 imm8) const { xOpWrite0F(0x66, 0xc5, to, from, imm8); } + void SimdImpl_PExtract::W(const xIndirectVoid& dest, const xRegisterSSE& from, u8 imm8) const { xOpWrite0F(0x66, 0x153a, from, dest, imm8); } + + const xImplSimd_Shuffle xSHUF = {}; + + const xImplSimd_PShuffle xPSHUF = + { + {0x66, 0x70}, // D + {0xf2, 0x70}, // LW + {0xf3, 0x70}, // HW + + {0x66, 0x0038}, // B + }; + + const SimdImpl_PUnpack xPUNPCK = + { + {0x66, 0x60}, // LBW + {0x66, 0x61}, // LWD + {0x66, 0x62}, // LDQ + {0x66, 0x6c}, // LQDQ + + {0x66, 0x68}, // HBW + {0x66, 0x69}, // HWD + {0x66, 0x6a}, // HDQ + {0x66, 0x6d}, // HQDQ + }; + + const SimdImpl_Pack xPACK = + { + {0x66, 0x63}, // SSWB + {0x66, 0x6b}, // SSDW + {0x66, 0x67}, // USWB + {0x66, 0x2b38}, // USDW + }; + + const xImplSimd_Unpack xUNPCK = + { + {0x00, 0x15}, // HPS + {0x66, 0x15}, // HPD + {0x00, 0x14}, // LPS + {0x66, 0x14}, // LPD + }; + + const xImplSimd_PInsert xPINSR = + { + {0x203a}, // B + {0x223a}, // D + }; + + const SimdImpl_PExtract xPEXTR = + { + {0x143a}, // B + {0x163a}, // D + }; + + // ===================================================================================================== + // SIMD Move And Blend Instructions + // ===================================================================================================== + + void xImplSimd_MovHL::PS(const xRegisterSSE& to, const xIndirectVoid& from) const { xOpWrite0F(Opcode, to, from); } + void xImplSimd_MovHL::PS(const xIndirectVoid& to, const xRegisterSSE& from) const { xOpWrite0F(Opcode + 1, from, to); } + + void xImplSimd_MovHL::PD(const xRegisterSSE& to, const xIndirectVoid& from) const { xOpWrite0F(0x66, Opcode, to, from); } + void xImplSimd_MovHL::PD(const xIndirectVoid& to, const xRegisterSSE& from) const { xOpWrite0F(0x66, Opcode + 1, from, to); } + + void xImplSimd_MovHL_RtoR::PS(const xRegisterSSE& to, const xRegisterSSE& from) const { xOpWrite0F(Opcode, to, from); } + void xImplSimd_MovHL_RtoR::PD(const xRegisterSSE& to, const xRegisterSSE& from) const { xOpWrite0F(0x66, Opcode, to, from); } + + static const u16 MovPS_OpAligned = 0x28; // Aligned [aps] form + static const u16 MovPS_OpUnaligned = 0x10; // unaligned [ups] form + + void xImplSimd_MoveSSE::operator()(const xRegisterSSE& to, const xRegisterSSE& from) const + { + if (to != from) + xOpWrite0F(Prefix, MovPS_OpAligned, to, from); + } + + void xImplSimd_MoveSSE::operator()(const xRegisterSSE& to, const xIndirectVoid& from) const + { + // ModSib form is aligned if it's displacement-only and the displacement is aligned: + bool isReallyAligned = isAligned || (((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty()); + + xOpWrite0F(Prefix, isReallyAligned ? MovPS_OpAligned : MovPS_OpUnaligned, to, from); + } + + void xImplSimd_MoveSSE::operator()(const xIndirectVoid& to, const xRegisterSSE& from) const + { + // ModSib form is aligned if it's displacement-only and the displacement is aligned: + bool isReallyAligned = isAligned || ((to.Displacement & 0x0f) == 0 && to.Index.IsEmpty() && to.Base.IsEmpty()); + xOpWrite0F(Prefix, isReallyAligned ? MovPS_OpAligned + 1 : MovPS_OpUnaligned + 1, from, to); + } + + static const u8 MovDQ_PrefixAligned = 0x66; // Aligned [dqa] form + static const u8 MovDQ_PrefixUnaligned = 0xf3; // unaligned [dqu] form + + void xImplSimd_MoveDQ::operator()(const xRegisterSSE& to, const xRegisterSSE& from) const + { + if (to != from) + xOpWrite0F(MovDQ_PrefixAligned, 0x6f, to, from); + } + + void xImplSimd_MoveDQ::operator()(const xRegisterSSE& to, const xIndirectVoid& from) const + { + // ModSib form is aligned if it's displacement-only and the displacement is aligned: + bool isReallyAligned = isAligned || ((from.Displacement & 0x0f) == 0 && from.Index.IsEmpty() && from.Base.IsEmpty()); + xOpWrite0F(isReallyAligned ? MovDQ_PrefixAligned : MovDQ_PrefixUnaligned, 0x6f, to, from); + } + + void xImplSimd_MoveDQ::operator()(const xIndirectVoid& to, const xRegisterSSE& from) const + { + // ModSib form is aligned if it's displacement-only and the displacement is aligned: + bool isReallyAligned = isAligned || ((to.Displacement & 0x0f) == 0 && to.Index.IsEmpty() && to.Base.IsEmpty()); + + // use opcode 0x7f : alternate ModRM encoding (reverse src/dst) + xOpWrite0F(isReallyAligned ? MovDQ_PrefixAligned : MovDQ_PrefixUnaligned, 0x7f, from, to); + } + + void xImplSimd_PMove::BW(const xRegisterSSE& to, const xRegisterSSE& from) const { OpWriteSSE(0x66, OpcodeBase); } + void xImplSimd_PMove::BW(const xRegisterSSE& to, const xIndirect64& from) const { OpWriteSSE(0x66, OpcodeBase); } + + void xImplSimd_PMove::BD(const xRegisterSSE& to, const xRegisterSSE& from) const { OpWriteSSE(0x66, OpcodeBase + 0x100); } + void xImplSimd_PMove::BD(const xRegisterSSE& to, const xIndirect32& from) const { OpWriteSSE(0x66, OpcodeBase + 0x100); } + + void xImplSimd_PMove::BQ(const xRegisterSSE& to, const xRegisterSSE& from) const { OpWriteSSE(0x66, OpcodeBase + 0x200); } + void xImplSimd_PMove::BQ(const xRegisterSSE& to, const xIndirect16& from) const { OpWriteSSE(0x66, OpcodeBase + 0x200); } + + void xImplSimd_PMove::WD(const xRegisterSSE& to, const xRegisterSSE& from) const { OpWriteSSE(0x66, OpcodeBase + 0x300); } + void xImplSimd_PMove::WD(const xRegisterSSE& to, const xIndirect64& from) const { OpWriteSSE(0x66, OpcodeBase + 0x300); } + + void xImplSimd_PMove::WQ(const xRegisterSSE& to, const xRegisterSSE& from) const { OpWriteSSE(0x66, OpcodeBase + 0x400); } + void xImplSimd_PMove::WQ(const xRegisterSSE& to, const xIndirect32& from) const { OpWriteSSE(0x66, OpcodeBase + 0x400); } + + void xImplSimd_PMove::DQ(const xRegisterSSE& to, const xRegisterSSE& from) const { OpWriteSSE(0x66, OpcodeBase + 0x500); } + void xImplSimd_PMove::DQ(const xRegisterSSE& to, const xIndirect64& from) const { OpWriteSSE(0x66, OpcodeBase + 0x500); } + + + const xImplSimd_MoveSSE xMOVAPS = {0x00, true}; + const xImplSimd_MoveSSE xMOVUPS = {0x00, false}; #ifdef ALWAYS_USE_MOVAPS -const xImplSimd_MoveSSE xMOVDQA = {0x00, true}; -const xImplSimd_MoveSSE xMOVAPD = {0x00, true}; + const xImplSimd_MoveSSE xMOVDQA = {0x00, true}; + const xImplSimd_MoveSSE xMOVAPD = {0x00, true}; -const xImplSimd_MoveSSE xMOVDQU = {0x00, false}; -const xImplSimd_MoveSSE xMOVUPD = {0x00, false}; + const xImplSimd_MoveSSE xMOVDQU = {0x00, false}; + const xImplSimd_MoveSSE xMOVUPD = {0x00, false}; #else -const xImplSimd_MoveDQ xMOVDQA = {0x66, true}; -const xImplSimd_MoveSSE xMOVAPD = {0x66, true}; + const xImplSimd_MoveDQ xMOVDQA = {0x66, true}; + const xImplSimd_MoveSSE xMOVAPD = {0x66, true}; -const xImplSimd_MoveDQ xMOVDQU = {0xf3, false}; -const xImplSimd_MoveSSE xMOVUPD = {0x66, false}; + const xImplSimd_MoveDQ xMOVDQU = {0xf3, false}; + const xImplSimd_MoveSSE xMOVUPD = {0x66, false}; #endif -const xImplSimd_MovHL xMOVH = {0x16}; -const xImplSimd_MovHL xMOVL = {0x12}; + const xImplSimd_MovHL xMOVH = {0x16}; + const xImplSimd_MovHL xMOVL = {0x12}; -const xImplSimd_MovHL_RtoR xMOVLH = {0x16}; -const xImplSimd_MovHL_RtoR xMOVHL = {0x12}; + const xImplSimd_MovHL_RtoR xMOVLH = {0x16}; + const xImplSimd_MovHL_RtoR xMOVHL = {0x12}; -const xImplSimd_Blend xBLEND = - { - {0x66, 0x0c3a}, // PS - {0x66, 0x0d3a}, // PD - {0x66, 0x1438}, // VPS - {0x66, 0x1538}, // VPD -}; + const xImplSimd_Blend xBLEND = + { + {0x66, 0x0c3a}, // PS + {0x66, 0x0d3a}, // PD + {0x66, 0x1438}, // VPS + {0x66, 0x1538}, // VPD + }; -const xImplSimd_PMove xPMOVSX = {0x2038}; -const xImplSimd_PMove xPMOVZX = {0x3038}; + const xImplSimd_PMove xPMOVSX = {0x2038}; + const xImplSimd_PMove xPMOVZX = {0x3038}; -// [SSE-3] -const xImplSimd_DestRegSSE xMOVSLDUP = {0xf3, 0x12}; + // [SSE-3] + const xImplSimd_DestRegSSE xMOVSLDUP = {0xf3, 0x12}; -// [SSE-3] -const xImplSimd_DestRegSSE xMOVSHDUP = {0xf3, 0x16}; + // [SSE-3] + const xImplSimd_DestRegSSE xMOVSHDUP = {0xf3, 0x16}; -////////////////////////////////////////////////////////////////////////////////////////// -// MMX Mov Instructions (MOVD, MOVQ, MOVSS). -// -// Notes: -// * Some of the functions have been renamed to more clearly reflect what they actually -// do. Namely we've affixed "ZX" to several MOVs that take a register as a destination -// since that's what they do (MOVD clears upper 32/96 bits, etc). -// -// * MOVD has valid forms for MMX and XMM registers. -// + ////////////////////////////////////////////////////////////////////////////////////////// + // MMX Mov Instructions (MOVD, MOVQ, MOVSS). + // + // Notes: + // * Some of the functions have been renamed to more clearly reflect what they actually + // do. Namely we've affixed "ZX" to several MOVs that take a register as a destination + // since that's what they do (MOVD clears upper 32/96 bits, etc). + // + // * MOVD has valid forms for MMX and XMM registers. + // -__fi void xMOVDZX(const xRegisterSSE &to, const xRegister32or64 &from) { xOpWrite0F(0x66, 0x6e, to, from); } -__fi void xMOVDZX(const xRegisterSSE &to, const xIndirectVoid &src) { xOpWrite0F(0x66, 0x6e, to, src); } + __fi void xMOVDZX(const xRegisterSSE& to, const xRegister32or64& from) { xOpWrite0F(0x66, 0x6e, to, from); } + __fi void xMOVDZX(const xRegisterSSE& to, const xIndirectVoid& src) { xOpWrite0F(0x66, 0x6e, to, src); } -__fi void xMOVD(const xRegister32or64 &to, const xRegisterSSE &from) { xOpWrite0F(0x66, 0x7e, from, to); } -__fi void xMOVD(const xIndirectVoid &dest, const xRegisterSSE &from) { xOpWrite0F(0x66, 0x7e, from, dest); } + __fi void xMOVD(const xRegister32or64& to, const xRegisterSSE& from) { xOpWrite0F(0x66, 0x7e, from, to); } + __fi void xMOVD(const xIndirectVoid& dest, const xRegisterSSE& from) { xOpWrite0F(0x66, 0x7e, from, dest); } -// Moves from XMM to XMM, with the *upper 64 bits* of the destination register -// being cleared to zero. -__fi void xMOVQZX(const xRegisterSSE &to, const xRegisterSSE &from) { xOpWrite0F(0xf3, 0x7e, to, from); } + // Moves from XMM to XMM, with the *upper 64 bits* of the destination register + // being cleared to zero. + __fi void xMOVQZX(const xRegisterSSE& to, const xRegisterSSE& from) { xOpWrite0F(0xf3, 0x7e, to, from); } -// Moves from XMM to XMM, with the *upper 64 bits* of the destination register -// being cleared to zero. -__fi void xMOVQZX(const xRegisterSSE &to, const xIndirectVoid &src) { xOpWrite0F(0xf3, 0x7e, to, src); } + // Moves from XMM to XMM, with the *upper 64 bits* of the destination register + // being cleared to zero. + __fi void xMOVQZX(const xRegisterSSE& to, const xIndirectVoid& src) { xOpWrite0F(0xf3, 0x7e, to, src); } -// Moves from XMM to XMM, with the *upper 64 bits* of the destination register -// being cleared to zero. -__fi void xMOVQZX(const xRegisterSSE &to, const void *src) { xOpWrite0F(0xf3, 0x7e, to, src); } + // Moves from XMM to XMM, with the *upper 64 bits* of the destination register + // being cleared to zero. + __fi void xMOVQZX(const xRegisterSSE& to, const void* src) { xOpWrite0F(0xf3, 0x7e, to, src); } -// Moves lower quad of XMM to ptr64 (no bits are cleared) -__fi void xMOVQ(const xIndirectVoid &dest, const xRegisterSSE &from) { xOpWrite0F(0x66, 0xd6, from, dest); } + // Moves lower quad of XMM to ptr64 (no bits are cleared) + __fi void xMOVQ(const xIndirectVoid& dest, const xRegisterSSE& from) { xOpWrite0F(0x66, 0xd6, from, dest); } -////////////////////////////////////////////////////////////////////////////////////////// -// + ////////////////////////////////////////////////////////////////////////////////////////// + // -#define IMPLEMENT_xMOVS(ssd, prefix) \ - __fi void xMOV##ssd(const xRegisterSSE &to, const xRegisterSSE &from) \ - { \ - if (to != from) \ - xOpWrite0F(prefix, 0x10, to, from); \ - } \ - __fi void xMOV##ssd##ZX(const xRegisterSSE &to, const xIndirectVoid &from) { xOpWrite0F(prefix, 0x10, to, from); } \ - __fi void xMOV##ssd(const xIndirectVoid &to, const xRegisterSSE &from) { xOpWrite0F(prefix, 0x11, from, to); } +#define IMPLEMENT_xMOVS(ssd, prefix) \ + __fi void xMOV##ssd(const xRegisterSSE& to, const xRegisterSSE& from) \ + { \ + if (to != from) \ + xOpWrite0F(prefix, 0x10, to, from); \ + } \ + __fi void xMOV##ssd##ZX(const xRegisterSSE& to, const xIndirectVoid& from) { xOpWrite0F(prefix, 0x10, to, from); } \ + __fi void xMOV##ssd(const xIndirectVoid& to, const xRegisterSSE& from) { xOpWrite0F(prefix, 0x11, from, to); } -IMPLEMENT_xMOVS(SS, 0xf3) - IMPLEMENT_xMOVS(SD, 0xf2) + IMPLEMENT_xMOVS(SS, 0xf3) + IMPLEMENT_xMOVS(SD, 0xf2) - ////////////////////////////////////////////////////////////////////////////////////////// - // Non-temporal movs only support a register as a target (ie, load form only, no stores) - // + ////////////////////////////////////////////////////////////////////////////////////////// + // Non-temporal movs only support a register as a target (ie, load form only, no stores) + // - __fi void xMOVNTDQA(const xRegisterSSE &to, const xIndirectVoid &from) -{ - xOpWrite0F(0x66, 0x2a38, to.Id, from); -} + __fi void xMOVNTDQA(const xRegisterSSE& to, const xIndirectVoid& from) + { + xOpWrite0F(0x66, 0x2a38, to.Id, from); + } -__fi void xMOVNTDQA(const xIndirectVoid &to, const xRegisterSSE &from) { xOpWrite0F(0x66, 0xe7, from, to); } + __fi void xMOVNTDQA(const xIndirectVoid& to, const xRegisterSSE& from) { xOpWrite0F(0x66, 0xe7, from, to); } -__fi void xMOVNTPD(const xIndirectVoid &to, const xRegisterSSE &from) { xOpWrite0F(0x66, 0x2b, from, to); } -__fi void xMOVNTPS(const xIndirectVoid &to, const xRegisterSSE &from) { xOpWrite0F(0x2b, from, to); } + __fi void xMOVNTPD(const xIndirectVoid& to, const xRegisterSSE& from) { xOpWrite0F(0x66, 0x2b, from, to); } + __fi void xMOVNTPS(const xIndirectVoid& to, const xRegisterSSE& from) { xOpWrite0F(0x2b, from, to); } -// ------------------------------------------------------------------------ + // ------------------------------------------------------------------------ -__fi void xMOVMSKPS(const xRegister32 &to, const xRegisterSSE &from) { xOpWrite0F(0x50, to, from); } -__fi void xMOVMSKPD(const xRegister32 &to, const xRegisterSSE &from) { xOpWrite0F(0x66, 0x50, to, from, true); } + __fi void xMOVMSKPS(const xRegister32& to, const xRegisterSSE& from) { xOpWrite0F(0x50, to, from); } + __fi void xMOVMSKPD(const xRegister32& to, const xRegisterSSE& from) { xOpWrite0F(0x66, 0x50, to, from, true); } -// xMASKMOV: -// Selectively write bytes from mm1/xmm1 to memory location using the byte mask in mm2/xmm2. -// The default memory location is specified by DS:EDI. The most significant bit in each byte -// of the mask operand determines whether the corresponding byte in the source operand is -// written to the corresponding byte location in memory. -__fi void xMASKMOV(const xRegisterSSE &to, const xRegisterSSE &from) { xOpWrite0F(0x66, 0xf7, to, from); } + // xMASKMOV: + // Selectively write bytes from mm1/xmm1 to memory location using the byte mask in mm2/xmm2. + // The default memory location is specified by DS:EDI. The most significant bit in each byte + // of the mask operand determines whether the corresponding byte in the source operand is + // written to the corresponding byte location in memory. + __fi void xMASKMOV(const xRegisterSSE& to, const xRegisterSSE& from) { xOpWrite0F(0x66, 0xf7, to, from); } -// xPMOVMSKB: -// Creates a mask made up of the most significant bit of each byte of the source -// operand and stores the result in the low byte or word of the destination operand. -// Upper bits of the destination are cleared to zero. -// -// When operating on a 64-bit (MMX) source, the byte mask is 8 bits; when operating on -// 128-bit (SSE) source, the byte mask is 16-bits. -// -__fi void xPMOVMSKB(const xRegister32or64 &to, const xRegisterSSE &from) { xOpWrite0F(0x66, 0xd7, to, from); } + // xPMOVMSKB: + // Creates a mask made up of the most significant bit of each byte of the source + // operand and stores the result in the low byte or word of the destination operand. + // Upper bits of the destination are cleared to zero. + // + // When operating on a 64-bit (MMX) source, the byte mask is 8 bits; when operating on + // 128-bit (SSE) source, the byte mask is 16-bits. + // + __fi void xPMOVMSKB(const xRegister32or64& to, const xRegisterSSE& from) { xOpWrite0F(0x66, 0xd7, to, from); } -// [sSSE-3] Concatenates dest and source operands into an intermediate composite, -// shifts the composite at byte granularity to the right by a constant immediate, -// and extracts the right-aligned result into the destination. -// -__fi void xPALIGNR(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm8) { xOpWrite0F(0x66, 0x0f3a, to, from, imm8); } + // [sSSE-3] Concatenates dest and source operands into an intermediate composite, + // shifts the composite at byte granularity to the right by a constant immediate, + // and extracts the right-aligned result into the destination. + // + __fi void xPALIGNR(const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8) { xOpWrite0F(0x66, 0x0f3a, to, from, imm8); } -// -------------------------------------------------------------------------------------- -// INSERTPS / EXTRACTPS [SSE4.1 only!] -// -------------------------------------------------------------------------------------- -// [TODO] these might be served better as classes, especially if other instructions use -// the M32,sse,imm form (I forget offhand if any do). + // -------------------------------------------------------------------------------------- + // INSERTPS / EXTRACTPS [SSE4.1 only!] + // -------------------------------------------------------------------------------------- + // [TODO] these might be served better as classes, especially if other instructions use + // the M32,sse,imm form (I forget offhand if any do). -// [SSE-4.1] Insert a single-precision floating-point value from src into a specified -// location in dest, and selectively zero out the data elements in dest according to -// the mask field in the immediate byte. The source operand can be a memory location -// (32 bits) or an XMM register (lower 32 bits used). -// -// Imm8 provides three fields: -// * COUNT_S: The value of Imm8[7:6] selects the dword element from src. It is 0 if -// the source is a memory operand. -// * COUNT_D: The value of Imm8[5:4] selects the target dword element in dest. -// * ZMASK: Each bit of Imm8[3:0] selects a dword element in dest to be written -// with 0.0 if set to 1. -// -__emitinline void xINSERTPS(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm8) { xOpWrite0F(0x66, 0x213a, to, from, imm8); } -__emitinline void xINSERTPS(const xRegisterSSE &to, const xIndirect32 &from, u8 imm8) { xOpWrite0F(0x66, 0x213a, to, from, imm8); } + // [SSE-4.1] Insert a single-precision floating-point value from src into a specified + // location in dest, and selectively zero out the data elements in dest according to + // the mask field in the immediate byte. The source operand can be a memory location + // (32 bits) or an XMM register (lower 32 bits used). + // + // Imm8 provides three fields: + // * COUNT_S: The value of Imm8[7:6] selects the dword element from src. It is 0 if + // the source is a memory operand. + // * COUNT_D: The value of Imm8[5:4] selects the target dword element in dest. + // * ZMASK: Each bit of Imm8[3:0] selects a dword element in dest to be written + // with 0.0 if set to 1. + // + __emitinline void xINSERTPS(const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8) { xOpWrite0F(0x66, 0x213a, to, from, imm8); } + __emitinline void xINSERTPS(const xRegisterSSE& to, const xIndirect32& from, u8 imm8) { xOpWrite0F(0x66, 0x213a, to, from, imm8); } -// [SSE-4.1] Extract a single-precision floating-point value from src at an offset -// determined by imm8[1-0]*32. The extracted single precision floating-point value -// is stored into the low 32-bits of dest (or at a 32-bit memory pointer). -// -__emitinline void xEXTRACTPS(const xRegister32or64 &to, const xRegisterSSE &from, u8 imm8) { xOpWrite0F(0x66, 0x173a, to, from, imm8); } -__emitinline void xEXTRACTPS(const xIndirect32 &dest, const xRegisterSSE &from, u8 imm8) { xOpWrite0F(0x66, 0x173a, from, dest, imm8); } + // [SSE-4.1] Extract a single-precision floating-point value from src at an offset + // determined by imm8[1-0]*32. The extracted single precision floating-point value + // is stored into the low 32-bits of dest (or at a 32-bit memory pointer). + // + __emitinline void xEXTRACTPS(const xRegister32or64& to, const xRegisterSSE& from, u8 imm8) { xOpWrite0F(0x66, 0x173a, to, from, imm8); } + __emitinline void xEXTRACTPS(const xIndirect32& dest, const xRegisterSSE& from, u8 imm8) { xOpWrite0F(0x66, 0x173a, from, dest, imm8); } -// ===================================================================================================== -// Ungrouped Instructions! -// ===================================================================================================== + // ===================================================================================================== + // Ungrouped Instructions! + // ===================================================================================================== -// Store Streaming SIMD Extension Control/Status to Mem32. -__emitinline void xSTMXCSR(const xIndirect32 &dest) -{ - xOpWrite0F(0, 0xae, 3, dest); -} + // Store Streaming SIMD Extension Control/Status to Mem32. + __emitinline void xSTMXCSR(const xIndirect32& dest) + { + xOpWrite0F(0, 0xae, 3, dest); + } -// Load Streaming SIMD Extension Control/Status from Mem32. -__emitinline void xLDMXCSR(const xIndirect32 &src) -{ - xOpWrite0F(0, 0xae, 2, src); -} + // Load Streaming SIMD Extension Control/Status from Mem32. + __emitinline void xLDMXCSR(const xIndirect32& src) + { + xOpWrite0F(0, 0xae, 2, src); + } -// Save x87 FPU, MMX Technology, and SSE State to buffer -// Target buffer must be at least 512 bytes in length to hold the result. -__emitinline void xFXSAVE(const xIndirectVoid &dest) -{ - xOpWrite0F(0, 0xae, 0, dest); -} + // Save x87 FPU, MMX Technology, and SSE State to buffer + // Target buffer must be at least 512 bytes in length to hold the result. + __emitinline void xFXSAVE(const xIndirectVoid& dest) + { + xOpWrite0F(0, 0xae, 0, dest); + } -// Restore x87 FPU, MMX , XMM, and MXCSR State. -// Source buffer should be 512 bytes in length. -__emitinline void xFXRSTOR(const xIndirectVoid &src) -{ - xOpWrite0F(0, 0xae, 1, src); -} -} + // Restore x87 FPU, MMX , XMM, and MXCSR State. + // Source buffer should be 512 bytes in length. + __emitinline void xFXRSTOR(const xIndirectVoid& src) + { + xOpWrite0F(0, 0xae, 1, src); + } +} // namespace x86Emitter diff --git a/common/emitter/tools.h b/common/emitter/tools.h index 9889f76841..93af5c359d 100644 --- a/common/emitter/tools.h +++ b/common/emitter/tools.h @@ -17,10 +17,11 @@ #include "common/Dependencies.h" -enum x86VendorType { - x86Vendor_Intel = 0, - x86Vendor_AMD = 1, - x86Vendor_Unknown = 2 +enum x86VendorType +{ + x86Vendor_Intel = 0, + x86Vendor_AMD = 1, + x86Vendor_Unknown = 2 }; // -------------------------------------------------------------------------------------- @@ -29,117 +30,120 @@ 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); // Predeclaration for xIndirect32 -namespace x86Emitter { - template class xIndirect; +namespace x86Emitter +{ + template + class xIndirect; typedef xIndirect xIndirect32; -} +} // namespace x86Emitter // -------------------------------------------------------------------------------------- // SSE_MXCSR - Control/Status Register (bitfield) @@ -153,52 +157,52 @@ namespace x86Emitter { // 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; diff --git a/common/emitter/x86emitter.cpp b/common/emitter/x86emitter.cpp index 8a79eccd5d..6398d8a024 100644 --- a/common/emitter/x86emitter.cpp +++ b/common/emitter/x86emitter.cpp @@ -60,54 +60,54 @@ // -__tls_emit u8 *x86Ptr; +__tls_emit u8* x86Ptr; __tls_emit XMMSSEType g_xmmtypes[iREGCNT_XMM] = {XMMT_INT}; namespace x86Emitter { -template void xWrite(u8 val); -template void xWrite(u16 val); -template void xWrite(u32 val); -template void xWrite(u64 val); -template void xWrite(u128 val); + template void xWrite(u8 val); + template void xWrite(u16 val); + template void xWrite(u32 val); + template void xWrite(u64 val); + template void xWrite(u128 val); -__fi void xWrite8(u8 val) -{ - xWrite(val); -} + __fi void xWrite8(u8 val) + { + xWrite(val); + } -__fi void xWrite16(u16 val) -{ - xWrite(val); -} + __fi void xWrite16(u16 val) + { + xWrite(val); + } -__fi void xWrite32(u32 val) -{ - xWrite(val); -} + __fi void xWrite32(u32 val) + { + xWrite(val); + } -__fi void xWrite64(u64 val) -{ - xWrite(val); -} + __fi void xWrite64(u64 val) + { + xWrite(val); + } -// Empty initializers are due to frivolously pointless GCC errors (it demands the -// objects be initialized even though they have no actual variable members). + // Empty initializers are due to frivolously pointless GCC errors (it demands the + // objects be initialized even though they have no actual variable members). -const xAddressIndexer ptr = {}; -const xAddressIndexer ptrNative = {}; -const xAddressIndexer ptr128 = {}; -const xAddressIndexer ptr64 = {}; -const xAddressIndexer ptr32 = {}; -const xAddressIndexer ptr16 = {}; -const xAddressIndexer ptr8 = {}; + const xAddressIndexer ptr = {}; + const xAddressIndexer ptrNative = {}; + const xAddressIndexer ptr128 = {}; + const xAddressIndexer ptr64 = {}; + const xAddressIndexer ptr32 = {}; + const xAddressIndexer ptr16 = {}; + const xAddressIndexer ptr8 = {}; -// ------------------------------------------------------------------------ + // ------------------------------------------------------------------------ -const xRegisterEmpty xEmptyReg = {}; + const xRegisterEmpty xEmptyReg = {}; -// clang-format off + // clang-format off const xRegisterSSE xmm0(0), xmm1(1), @@ -186,949 +186,1016 @@ const xRegister32 calleeSavedReg2d = r13d; #endif -// clang-format on + // clang-format on -const xRegisterCL cl; + const xRegisterCL cl; -const char *const x86_regnames_gpr8[] = - { - "al", "cl", "dl", "bl", - "ah", "ch", "dh", "bh", - "b8", "b9", "b10", "b11", - "b12", "b13", "b14", "b15"}; + const char* const x86_regnames_gpr8[] = + { + "al", "cl", "dl", "bl", + "ah", "ch", "dh", "bh", + "b8", "b9", "b10", "b11", + "b12", "b13", "b14", "b15" + }; -const char *const x86_regnames_gpr16[] = - { - "ax", "cx", "dx", "bx", - "sp", "bp", "si", "di", - "h8", "h9", "h10", "h11", - "h12", "h13", "h14", "h15"}; + const char* const x86_regnames_gpr16[] = + { + "ax", "cx", "dx", "bx", + "sp", "bp", "si", "di", + "h8", "h9", "h10", "h11", + "h12", "h13", "h14", "h15" + }; -const char *const x86_regnames_gpr32[] = - { - "eax", "ecx", "edx", "ebx", - "esp", "ebp", "esi", "edi", - "e8", "e9", "e10", "e11", - "e12", "e13", "e14", "e15"}; + const char* const x86_regnames_gpr32[] = + { + "eax", "ecx", "edx", "ebx", + "esp", "ebp", "esi", "edi", + "e8", "e9", "e10", "e11", + "e12", "e13", "e14", "e15" + }; #ifdef __M_X86_64 -const char *const x86_regnames_gpr64[] = - { - "rax", "rcx", "rdx", "rbx", - "rsp", "rbp", "rsi", "rdi", - "r8", "r9", "r10", "r11", - "r12", "r13", "r14", "r15"}; + const char* const x86_regnames_gpr64[] = + { + "rax", "rcx", "rdx", "rbx", + "rsp", "rbp", "rsi", "rdi", + "r8", "r9", "r10", "r11", + "r12", "r13", "r14", "r15" + }; #endif -const char *const x86_regnames_sse[] = - { - "xmm0", "xmm1", "xmm2", "xmm3", - "xmm4", "xmm5", "xmm6", "xmm7", - "xmm8", "xmm9", "xmm10", "xmm11", - "xmm12", "xmm13", "xmm14", "xmm15"}; + const char* const x86_regnames_sse[] = + { + "xmm0", "xmm1", "xmm2", "xmm3", + "xmm4", "xmm5", "xmm6", "xmm7", + "xmm8", "xmm9", "xmm10", "xmm11", + "xmm12", "xmm13", "xmm14", "xmm15" + }; -const char *xRegisterBase::GetName() -{ - if (Id == xRegId_Invalid) - return "invalid"; - if (Id == xRegId_Empty) - return "empty"; + const char* xRegisterBase::GetName() + { + if (Id == xRegId_Invalid) + return "invalid"; + if (Id == xRegId_Empty) + return "empty"; - // bad error? Return a "big" error string. Might break formatting of register tables - // but that's the least of your worries if you see this baby. - if (Id >= (int)iREGCNT_GPR || Id < 0) - return "!Register index out of range!"; + // bad error? Return a "big" error string. Might break formatting of register tables + // but that's the least of your worries if you see this baby. + if (Id >= (int)iREGCNT_GPR || Id < 0) + return "!Register index out of range!"; - switch (GetOperandSize()) { - case 1: - return x86_regnames_gpr8[Id]; - case 2: - return x86_regnames_gpr16[Id]; - case 4: - return x86_regnames_gpr32[Id]; + switch (GetOperandSize()) + { + case 1: + return x86_regnames_gpr8[Id]; + case 2: + return x86_regnames_gpr16[Id]; + case 4: + return x86_regnames_gpr32[Id]; #ifdef __M_X86_64 - case 8: - return x86_regnames_gpr64[Id]; + case 8: + return x86_regnames_gpr64[Id]; #endif - case 16: - return x86_regnames_sse[Id]; - } + case 16: + return x86_regnames_sse[Id]; + } - return "oops?"; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// Performance note: VC++ wants to use byte/word register form for the following -// ModRM/SibSB constructors when we use xWrite, and furthermore unrolls the -// the shift using a series of ADDs for the following results: -// add cl,cl -// add cl,cl -// add cl,cl -// or cl,bl -// add cl,cl -// ... etc. -// -// This is unquestionably bad optimization by Core2 standard, an generates tons of -// register aliases and false dependencies. (although may have been ideal for early- -// brand P4s with a broken barrel shifter?). The workaround is to do our own manual -// x86Ptr access and update using a u32 instead of u8. Thanks to little endianness, -// the same end result is achieved and no false dependencies are generated. The draw- -// back is that it clobbers 3 bytes past the end of the write, which could cause a -// headache for someone who himself is doing some kind of headache-inducing amount of -// recompiler SMC. So we don't do a work-around, and just hope for the compiler to -// stop sucking someday instead. :) -// -// (btw, I know this isn't a critical performance item by any means, but it's -// annoying simply because it *should* be an easy thing to optimize) - -static __fi void ModRM(uint mod, uint reg, uint rm) -{ - xWrite8((mod << 6) | (reg << 3) | rm); -} - -static __fi void SibSB(u32 ss, u32 index, u32 base) -{ - xWrite8((ss << 6) | (index << 3) | base); -} - -void EmitSibMagic(uint regfield, const void *address, int extraRIPOffset) -{ - sptr displacement = (sptr)address; -#ifndef __M_X86_64 - ModRM(0, regfield, ModRm_UseDisp32); -#else - sptr ripRelative = (sptr)address - ((sptr)x86Ptr + sizeof(s8) + sizeof(s32) + extraRIPOffset); - // Can we use a rip-relative address? (Prefer this over eiz because it's a byte shorter) - if (ripRelative == (s32)ripRelative) { - ModRM(0, regfield, ModRm_UseDisp32); - displacement = ripRelative; - } else { - pxAssertDev(displacement == (s32)displacement, "SIB target is too far away, needs an indirect register"); - ModRM(0, regfield, ModRm_UseSib); - SibSB(0, Sib_EIZ, Sib_UseDisp32); - } -#endif - - xWrite((s32)displacement); -} - -////////////////////////////////////////////////////////////////////////////////////////// -// returns TRUE if this instruction requires SIB to be encoded, or FALSE if the -// instruction ca be encoded as ModRm alone. -static __fi bool NeedsSibMagic(const xIndirectVoid &info) -{ - // no registers? no sibs! - // (xIndirectVoid::Reduce always places a register in Index, and optionally leaves - // Base empty if only register is specified) - if (info.Index.IsEmpty()) - return false; - - // A scaled register needs a SIB - if (info.Scale != 0) - return true; - - // two registers needs a SIB - if (!info.Base.IsEmpty()) - return true; - - return false; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// Conditionally generates Sib encoding information! -// -// regfield - register field to be written to the ModRm. This is either a register specifier -// or an opcode extension. In either case, the instruction determines the value for us. -// -void EmitSibMagic(uint regfield, const xIndirectVoid &info, int extraRIPOffset) -{ - // 3 bits also on x86_64 (so max is 8) - // We might need to mask it on x86_64 - pxAssertDev(regfield < 8, "Invalid x86 register identifier."); - int displacement_size = (info.Displacement == 0) ? 0 : - ((info.IsByteSizeDisp()) ? 1 : 2); - - pxAssert(!info.Base.IsEmpty() || !info.Index.IsEmpty() || displacement_size == 2); - // Displacement is only 64 bits for rip-relative addressing - pxAssert(info.Displacement == (s32)info.Displacement || (info.Base.IsEmpty() && info.Index.IsEmpty())); - - if (!NeedsSibMagic(info)) { - // Use ModRm-only encoding, with the rm field holding an index/base register, if - // one has been specified. If neither register is specified then use Disp32 form, - // which is encoded as "EBP w/o displacement" (which is why EBP must always be - // encoded *with* a displacement of 0, if it would otherwise not have one). - - if (info.Index.IsEmpty()) { - EmitSibMagic(regfield, (void *)info.Displacement, extraRIPOffset); - return; - } else { - if (info.Index == rbp && displacement_size == 0) - displacement_size = 1; // forces [ebp] to be encoded as [ebp+0]! - - ModRM(displacement_size, regfield, info.Index.Id & 7); - } - } else { - // In order to encode "just" index*scale (and no base), we have to encode - // it as a special [index*scale + displacement] form, which is done by - // specifying EBP as the base register and setting the displacement field - // to zero. (same as ModRm w/o SIB form above, basically, except the - // ModRm_UseDisp flag is specified in the SIB instead of the ModRM field). - - if (info.Base.IsEmpty()) { - ModRM(0, regfield, ModRm_UseSib); - SibSB(info.Scale, info.Index.Id, Sib_UseDisp32); - xWrite(info.Displacement); - return; - } else { - if (info.Base == rbp && displacement_size == 0) - displacement_size = 1; // forces [ebp] to be encoded as [ebp+0]! - - ModRM(displacement_size, regfield, ModRm_UseSib); - SibSB(info.Scale, info.Index.Id & 7, info.Base.Id & 7); - } - } - - if (displacement_size != 0) { - if (displacement_size == 1) - xWrite(info.Displacement); - else - xWrite(info.Displacement); - } -} - -// Writes a ModRM byte for "Direct" register access forms, which is used for all -// instructions taking a form of [reg,reg]. -void EmitSibMagic(uint reg1, const xRegisterBase ®2, int) -{ - xWrite8((Mod_Direct << 6) | (reg1 << 3) | (reg2.Id & 7)); -} - -void EmitSibMagic(const xRegisterBase ®1, const xRegisterBase ®2, int) -{ - xWrite8((Mod_Direct << 6) | ((reg1.Id & 7) << 3) | (reg2.Id & 7)); -} - -void EmitSibMagic(const xRegisterBase ®1, const void *src, int extraRIPOffset) -{ - EmitSibMagic(reg1.Id & 7, src, extraRIPOffset); -} - -void EmitSibMagic(const xRegisterBase ®1, const xIndirectVoid &sib, int extraRIPOffset) -{ - EmitSibMagic(reg1.Id & 7, sib, extraRIPOffset); -} - -////////////////////////////////////////////////////////////////////////////////////////// -__emitinline static void EmitRex(bool w, bool r, bool x, bool b) -{ -#ifdef __M_X86_64 - const u8 rex = 0x40 | (w << 3) | (r << 2) | (x << 1) | (u8)b; - if (rex != 0x40) - xWrite8(rex); -#endif -} - -void EmitRex(uint regfield, const void *address) -{ - pxAssert(0); - bool w = false; - bool r = false; - bool x = false; - bool b = false; - EmitRex(w, r, x, b); -} - -void EmitRex(uint regfield, const xIndirectVoid &info) -{ - bool w = info.IsWide(); - bool r = false; - bool x = info.Index.IsExtended(); - bool b = info.Base.IsExtended(); - if (!NeedsSibMagic(info)) { - b = x; - x = false; + return "oops?"; } - EmitRex(w, r, x, b); -} -void EmitRex(uint reg1, const xRegisterBase ®2) -{ - bool w = reg2.IsWide(); - bool r = false; - bool x = false; - bool b = reg2.IsExtended(); - EmitRex(w, r, x, b); -} - -void EmitRex(const xRegisterBase ®1, const xRegisterBase ®2) -{ - bool w = reg1.IsWide(); - bool r = reg1.IsExtended(); - bool x = false; - bool b = reg2.IsExtended(); - EmitRex(w, r, x, b); -} - -void EmitRex(const xRegisterBase ®1, const void *src) -{ - pxAssert(0); //see fixme - bool w = reg1.IsWide(); - bool r = reg1.IsExtended(); - bool x = false; - bool b = false; // FIXME src.IsExtended(); - EmitRex(w, r, x, b); -} - -void EmitRex(const xRegisterBase ®1, const xIndirectVoid &sib) -{ - bool w = reg1.IsWide(); - bool r = reg1.IsExtended(); - bool x = sib.Index.IsExtended(); - bool b = sib.Base.IsExtended(); - if (!NeedsSibMagic(sib)) { - b = x; - x = false; - } - EmitRex(w, r, x, b); -} - -// For use by instructions that are implicitly wide -void EmitRexImplicitlyWide(const xRegisterBase ®) -{ - bool w = false; - bool r = false; - bool x = false; - bool b = reg.IsExtended(); - EmitRex(w, r, x, b); -} - -void EmitRexImplicitlyWide(const xIndirectVoid &sib) -{ - bool w = false; - bool r = false; - bool x = sib.Index.IsExtended(); - bool b = sib.Base.IsExtended(); - if (!NeedsSibMagic(sib)) { - b = x; - x = false; - } - EmitRex(w, r, x, b); -} - - -// -------------------------------------------------------------------------------------- -// xSetPtr / xAlignPtr / xGetPtr / xAdvancePtr -// -------------------------------------------------------------------------------------- - -// Assigns the current emitter buffer target address. -// This is provided instead of using x86Ptr directly, since we may in the future find -// a need to change the storage class system for the x86Ptr 'under the hood.' -__emitinline void xSetPtr(void *ptr) -{ - x86Ptr = (u8 *)ptr; -} - -// Retrieves the current emitter buffer target address. -// This is provided instead of using x86Ptr directly, since we may in the future find -// a need to change the storage class system for the x86Ptr 'under the hood.' -__emitinline u8 *xGetPtr() -{ - return x86Ptr; -} - -__emitinline void xAlignPtr(uint bytes) -{ - // forward align - x86Ptr = (u8 *)(((uptr)x86Ptr + bytes - 1) & ~(uptr)(bytes - 1)); -} - -// Performs best-case alignment for the target CPU, for use prior to starting a new -// function. This is not meant to be used prior to jump targets, since it doesn't -// add padding (additionally, speed benefit from jump alignment is minimal, and often -// a loss). -__emitinline void xAlignCallTarget() -{ - // Core2/i7 CPUs prefer unaligned addresses. Checking for SSSE3 is a decent filter. - // (also align in debug modes for disasm convenience) - - if (IsDebugBuild || !x86caps.hasSupplementalStreamingSIMD3Extensions) { - // - P4's and earlier prefer 16 byte alignment. - // - AMD Athlons and Phenoms prefer 8 byte alignment, but I don't have an easy - // heuristic for it yet. - // - AMD Phenom IIs are unknown (either prefer 8 byte, or unaligned). - - xAlignPtr(16); - } -} - -__emitinline u8 *xGetAlignedCallTarget() -{ - xAlignCallTarget(); - return x86Ptr; -} - -__emitinline void xAdvancePtr(uint bytes) -{ - if (IsDevBuild) { - // common debugger courtesy: advance with INT3 as filler. - for (uint i = 0; i < bytes; i++) - xWrite8(0xcc); - } else - x86Ptr += bytes; -} - -// -------------------------------------------------------------------------------------- -// xRegisterInt (method implementations) -// -------------------------------------------------------------------------------------- -xRegisterInt xRegisterInt::MatchSizeTo(xRegisterInt other) const -{ - return other.GetOperandSize() == 1 - ? xRegisterInt(xRegister8(*this)) - : xRegisterInt(other.GetOperandSize(), Id); -} - -// -------------------------------------------------------------------------------------- -// xAddressReg (operator overloads) -// -------------------------------------------------------------------------------------- -xAddressVoid xAddressReg::operator+(const xAddressReg &right) const -{ - pxAssertMsg(right.Id != -1 || Id != -1, "Uninitialized x86 register."); - return xAddressVoid(*this, right); -} - -xAddressVoid xAddressReg::operator+(sptr right) const -{ - pxAssertMsg(Id != -1, "Uninitialized x86 register."); - return xAddressVoid(*this, right); -} - -xAddressVoid xAddressReg::operator+(const void *right) const -{ - pxAssertMsg(Id != -1, "Uninitialized x86 register."); - return xAddressVoid(*this, (sptr)right); -} - -xAddressVoid xAddressReg::operator-(sptr right) const -{ - pxAssertMsg(Id != -1, "Uninitialized x86 register."); - return xAddressVoid(*this, -right); -} - -xAddressVoid xAddressReg::operator-(const void *right) const -{ - pxAssertMsg(Id != -1, "Uninitialized x86 register."); - return xAddressVoid(*this, -(sptr)right); -} - -xAddressVoid xAddressReg::operator*(int factor) const -{ - pxAssertMsg(Id != -1, "Uninitialized x86 register."); - return xAddressVoid(xEmptyReg, *this, factor); -} - -xAddressVoid xAddressReg::operator<<(u32 shift) const -{ - pxAssertMsg(Id != -1, "Uninitialized x86 register."); - return xAddressVoid(xEmptyReg, *this, 1 << shift); -} - - -// -------------------------------------------------------------------------------------- -// xAddressVoid (method implementations) -// -------------------------------------------------------------------------------------- - -xAddressVoid::xAddressVoid(const xAddressReg &base, const xAddressReg &index, int factor, sptr displacement) -{ - Base = base; - Index = index; - Factor = factor; - Displacement = displacement; - - pxAssertMsg(base.Id != xRegId_Invalid, "Uninitialized x86 register."); - pxAssertMsg(index.Id != xRegId_Invalid, "Uninitialized x86 register."); -} - -xAddressVoid::xAddressVoid(const xAddressReg &index, sptr displacement) -{ - Base = xEmptyReg; - Index = index; - Factor = 0; - Displacement = displacement; - - pxAssertMsg(index.Id != xRegId_Invalid, "Uninitialized x86 register."); -} - -xAddressVoid::xAddressVoid(sptr displacement) -{ - Base = xEmptyReg; - Index = xEmptyReg; - Factor = 0; - Displacement = displacement; -} - -xAddressVoid::xAddressVoid(const void *displacement) -{ - Base = xEmptyReg; - Index = xEmptyReg; - Factor = 0; - Displacement = (sptr)displacement; -} - -xAddressVoid &xAddressVoid::Add(const xAddressReg &src) -{ - if (src == Index) { - Factor++; - } else if (src == Base) { - // Compound the existing register reference into the Index/Scale pair. - Base = xEmptyReg; - - if (src == Index) - Factor++; - else { - pxAssertDev(Index.IsEmpty(), "x86Emitter: Only one scaled index register is allowed in an address modifier."); - Index = src; - Factor = 2; - } - } else if (Base.IsEmpty()) - Base = src; - else if (Index.IsEmpty()) - Index = src; - else - pxAssumeDev(false, L"x86Emitter: address modifiers cannot have more than two index registers."); // oops, only 2 regs allowed per ModRm! - - return *this; -} - -xAddressVoid &xAddressVoid::Add(const xAddressVoid &src) -{ - Add(src.Base); - Add(src.Displacement); - - // If the factor is 1, we can just treat index like a base register also. - if (src.Factor == 1) { - Add(src.Index); - } else if (Index.IsEmpty()) { - Index = src.Index; - Factor = src.Factor; - } else if (Index == src.Index) { - Factor += src.Factor; - } else - pxAssumeDev(false, L"x86Emitter: address modifiers cannot have more than two index registers."); // oops, only 2 regs allowed per ModRm! - - return *this; -} - -xIndirectVoid::xIndirectVoid(const xAddressVoid &src) -{ - Base = src.Base; - Index = src.Index; - Scale = src.Factor; - Displacement = src.Displacement; - - Reduce(); -} - -xIndirectVoid::xIndirectVoid(sptr disp) -{ - Base = xEmptyReg; - Index = xEmptyReg; - Scale = 0; - Displacement = disp; - - // no reduction necessary :D -} - -xIndirectVoid::xIndirectVoid(xAddressReg base, xAddressReg index, int scale, sptr displacement) -{ - Base = base; - Index = index; - Scale = scale; - Displacement = displacement; - - Reduce(); -} - -// Generates a 'reduced' ModSib form, which has valid Base, Index, and Scale values. -// Necessary because by default ModSib compounds registers into Index when possible. -// -// If the ModSib is in illegal form ([Base + Index*5] for example) then an assertion -// followed by an InvalidParameter Exception will be tossed around in haphazard -// fashion. -// -// Optimization Note: Currently VC does a piss poor job of inlining this, even though -// constant propagation *should* resove it to little or no code (VC's constprop fails -// on C++ class initializers). There is a work around [using array initializers instead] -// but it's too much trouble for code that isn't performance critical anyway. -// And, with luck, maybe VC10 will optimize it better and make it a non-issue. :D -// -void xIndirectVoid::Reduce() -{ - if (Index.IsStackPointer()) { - // esp cannot be encoded as the index, so move it to the Base, if possible. - // note: intentionally leave index assigned to esp also (generates correct - // encoding later, since ESP cannot be encoded 'alone') - - pxAssert(Scale == 0); // esp can't have an index modifier! - pxAssert(Base.IsEmpty()); // base must be empty or else! - - Base = Index; - return; - } - - // If no index reg, then load the base register into the index slot. - if (Index.IsEmpty()) { - Index = Base; - Scale = 0; - if (!Base.IsStackPointer()) // prevent ESP from being encoded 'alone' - Base = xEmptyReg; - return; - } - - // The Scale has a series of valid forms, all shown here: - - switch (Scale) { - case 0: - break; - case 1: - Scale = 0; - break; - case 2: - Scale = 1; - break; - - case 3: // becomes [reg*2+reg] - pxAssertDev(Base.IsEmpty(), "Cannot scale an Index register by 3 when Base is not empty!"); - Base = Index; - Scale = 1; - break; - - case 4: - Scale = 2; - break; - - case 5: // becomes [reg*4+reg] - pxAssertDev(Base.IsEmpty(), "Cannot scale an Index register by 5 when Base is not empty!"); - Base = Index; - Scale = 2; - break; - - case 6: // invalid! - pxAssumeDev(false, "x86 asm cannot scale a register by 6."); - break; - - case 7: // so invalid! - pxAssumeDev(false, "x86 asm cannot scale a register by 7."); - break; - - case 8: - Scale = 3; - break; - case 9: // becomes [reg*8+reg] - pxAssertDev(Base.IsEmpty(), "Cannot scale an Index register by 9 when Base is not empty!"); - Base = Index; - Scale = 3; - break; - - jNO_DEFAULT - } -} - -xIndirectVoid &xIndirectVoid::Add(sptr imm) -{ - Displacement += imm; - return *this; -} - -// ------------------------------------------------------------------------ -// Internal implementation of EmitSibMagic which has been custom tailored -// to optimize special forms of the Lea instructions accordingly, such -// as when a LEA can be replaced with a "MOV reg,imm" or "MOV reg,reg". -// -// preserve_flags - set to ture to disable use of SHL on [Index*Base] forms -// of LEA, which alters flags states. -// -static void EmitLeaMagic(const xRegisterInt &to, const xIndirectVoid &src, bool preserve_flags) -{ - int displacement_size = (src.Displacement == 0) ? 0 : - ((src.IsByteSizeDisp()) ? 1 : 2); - - // See EmitSibMagic for commenting on SIB encoding. - - if (!NeedsSibMagic(src) && src.Displacement == (s32)src.Displacement) { - // LEA Land: means we have either 1-register encoding or just an offset. - // offset is encodable as an immediate MOV, and a register is encodable - // as a register MOV. - - if (src.Index.IsEmpty()) { - xMOV(to, src.Displacement); - return; - } - else if (displacement_size == 0) { - _xMovRtoR(to, src.Index.MatchSizeTo(to)); - return; - } else if (!preserve_flags) { - // encode as MOV and ADD combo. Make sure to use the immediate on the - // ADD since it can encode as an 8-bit sign-extended value. - - _xMovRtoR(to, src.Index.MatchSizeTo(to)); - xADD(to, src.Displacement); - return; - } - } else { - if (src.Base.IsEmpty()) { - if (!preserve_flags && (displacement_size == 0)) { - // Encode [Index*Scale] as a combination of Mov and Shl. - // This is more efficient because of the bloated LEA format which requires - // a 32 bit displacement, and the compact nature of the alternative. - // - // (this does not apply to older model P4s with the broken barrel shifter, - // but we currently aren't optimizing for that target anyway). - - _xMovRtoR(to, src.Index); - xSHL(to, src.Scale); - return; - } - } else { - if (src.Scale == 0) { - if (!preserve_flags) { - if (src.Index == rsp) { - // ESP is not encodable as an index (ix86 ignores it), thus: - _xMovRtoR(to, src.Base.MatchSizeTo(to)); // will do the trick! - if (src.Displacement) - xADD(to, src.Displacement); - return; - } else if (src.Displacement == 0) { - _xMovRtoR(to, src.Base.MatchSizeTo(to)); - _g1_EmitOp(G1Type_ADD, to, src.Index.MatchSizeTo(to)); - return; - } - } else if ((src.Index == rsp) && (src.Displacement == 0)) { - // special case handling of ESP as Index, which is replaceable with - // a single MOV even when preserve_flags is set! :D - - _xMovRtoR(to, src.Base.MatchSizeTo(to)); - return; - } - } - } - } - - xOpWrite(0, 0x8d, to, src); -} - -__emitinline void xLEA(xRegister64 to, const xIndirectVoid &src, bool preserve_flags) -{ - EmitLeaMagic(to, src, preserve_flags); -} - -__emitinline void xLEA(xRegister32 to, const xIndirectVoid &src, bool preserve_flags) -{ - EmitLeaMagic(to, src, preserve_flags); -} - -__emitinline void xLEA(xRegister16 to, const xIndirectVoid &src, bool preserve_flags) -{ - xWrite8(0x66); - EmitLeaMagic(to, src, preserve_flags); -} - -__emitinline u32* xLEA_Writeback(xAddressReg to) -{ -#ifdef __M_X86_64 - xOpWrite(0, 0x8d, to, ptr[(void*)(0xdcdcdcd + (uptr)xGetPtr() + 7)]); + ////////////////////////////////////////////////////////////////////////////////////////// + // Performance note: VC++ wants to use byte/word register form for the following + // ModRM/SibSB constructors when we use xWrite, and furthermore unrolls the + // the shift using a series of ADDs for the following results: + // add cl,cl + // add cl,cl + // add cl,cl + // or cl,bl + // add cl,cl + // ... etc. + // + // This is unquestionably bad optimization by Core2 standard, an generates tons of + // register aliases and false dependencies. (although may have been ideal for early- + // brand P4s with a broken barrel shifter?). The workaround is to do our own manual + // x86Ptr access and update using a u32 instead of u8. Thanks to little endianness, + // the same end result is achieved and no false dependencies are generated. The draw- + // back is that it clobbers 3 bytes past the end of the write, which could cause a + // headache for someone who himself is doing some kind of headache-inducing amount of + // recompiler SMC. So we don't do a work-around, and just hope for the compiler to + // stop sucking someday instead. :) + // + // (btw, I know this isn't a critical performance item by any means, but it's + // annoying simply because it *should* be an easy thing to optimize) + + static __fi void ModRM(uint mod, uint reg, uint rm) + { + xWrite8((mod << 6) | (reg << 3) | rm); + } + + static __fi void SibSB(u32 ss, u32 index, u32 base) + { + xWrite8((ss << 6) | (index << 3) | base); + } + + void EmitSibMagic(uint regfield, const void* address, int extraRIPOffset) + { + sptr displacement = (sptr)address; +#ifndef __M_X86_64 + ModRM(0, regfield, ModRm_UseDisp32); #else - xOpAccWrite(0, 0xb8 | to.Id, 0, to); - xWrite32(0xcdcdcdcd); + sptr ripRelative = (sptr)address - ((sptr)x86Ptr + sizeof(s8) + sizeof(s32) + extraRIPOffset); + // Can we use a rip-relative address? (Prefer this over eiz because it's a byte shorter) + if (ripRelative == (s32)ripRelative) + { + ModRM(0, regfield, ModRm_UseDisp32); + displacement = ripRelative; + } + else + { + pxAssertDev(displacement == (s32)displacement, "SIB target is too far away, needs an indirect register"); + ModRM(0, regfield, ModRm_UseSib); + SibSB(0, Sib_EIZ, Sib_UseDisp32); + } #endif - return (u32*)xGetPtr() - 1; -} -// ===================================================================================================== -// TEST / INC / DEC -// ===================================================================================================== -void xImpl_Test::operator()(const xRegisterInt &to, const xRegisterInt &from) const -{ - pxAssert(to.GetOperandSize() == from.GetOperandSize()); - xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0x84 : 0x85, from, to); -} + xWrite((s32)displacement); + } -void xImpl_Test::operator()(const xIndirect64orLess &dest, int imm) const -{ - xOpWrite(dest.GetPrefix16(), dest.Is8BitOp() ? 0xf6 : 0xf7, 0, dest, dest.GetImmSize()); - dest.xWriteImm(imm); -} + ////////////////////////////////////////////////////////////////////////////////////////// + // returns TRUE if this instruction requires SIB to be encoded, or FALSE if the + // instruction ca be encoded as ModRm alone. + static __fi bool NeedsSibMagic(const xIndirectVoid& info) + { + // no registers? no sibs! + // (xIndirectVoid::Reduce always places a register in Index, and optionally leaves + // Base empty if only register is specified) + if (info.Index.IsEmpty()) + return false; -void xImpl_Test::operator()(const xRegisterInt &to, int imm) const -{ - if (to.IsAccumulator()) { - xOpAccWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xa8 : 0xa9, 0, to); - } else { - xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xf6 : 0xf7, 0, to); - } - to.xWriteImm(imm); -} + // A scaled register needs a SIB + if (info.Scale != 0) + return true; -void xImpl_BitScan::operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from) const -{ - pxAssert(to->GetOperandSize() == from->GetOperandSize()); - xOpWrite0F(from->GetPrefix16(), Opcode, to, from); -} -void xImpl_BitScan::operator()(const xRegister16or32or64 &to, const xIndirectVoid &sibsrc) const -{ - xOpWrite0F(to->GetPrefix16(), Opcode, to, sibsrc); -} + // two registers needs a SIB + if (!info.Base.IsEmpty()) + return true; -void xImpl_IncDec::operator()(const xRegisterInt &to) const -{ - if (to.Is8BitOp()) { - u8 regfield = isDec ? 1 : 0; - xOpWrite(to.GetPrefix16(), 0xfe, regfield, to); - } else { - #ifdef __M_X86_64 - xOpWrite(to.GetPrefix16(), 0xff, isDec ? 1 : 0, to); - #else - to.prefix16(); - xWrite8((isDec ? 0x48 : 0x40) | to.Id); - #endif - } -} + return false; + } -void xImpl_IncDec::operator()(const xIndirect64orLess &to) const -{ - to.prefix16(); - xWrite8(to.Is8BitOp() ? 0xfe : 0xff); - EmitSibMagic(isDec ? 1 : 0, to); -} + ////////////////////////////////////////////////////////////////////////////////////////// + // Conditionally generates Sib encoding information! + // + // regfield - register field to be written to the ModRm. This is either a register specifier + // or an opcode extension. In either case, the instruction determines the value for us. + // + void EmitSibMagic(uint regfield, const xIndirectVoid& info, int extraRIPOffset) + { + // 3 bits also on x86_64 (so max is 8) + // We might need to mask it on x86_64 + pxAssertDev(regfield < 8, "Invalid x86 register identifier."); + int displacement_size = (info.Displacement == 0) ? 0 : + ((info.IsByteSizeDisp()) ? 1 : 2); -void xImpl_DwordShift::operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from, const xRegisterCL & /* clreg */) const -{ - pxAssert(to->GetOperandSize() == from->GetOperandSize()); - xOpWrite0F(from->GetPrefix16(), OpcodeBase + 1, to, from); -} + pxAssert(!info.Base.IsEmpty() || !info.Index.IsEmpty() || displacement_size == 2); + // Displacement is only 64 bits for rip-relative addressing + pxAssert(info.Displacement == (s32)info.Displacement || (info.Base.IsEmpty() && info.Index.IsEmpty())); -void xImpl_DwordShift::operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from, u8 shiftcnt) const -{ - pxAssert(to->GetOperandSize() == from->GetOperandSize()); - if (shiftcnt != 0) - xOpWrite0F(from->GetPrefix16(), OpcodeBase, to, from, shiftcnt); -} + if (!NeedsSibMagic(info)) + { + // Use ModRm-only encoding, with the rm field holding an index/base register, if + // one has been specified. If neither register is specified then use Disp32 form, + // which is encoded as "EBP w/o displacement" (which is why EBP must always be + // encoded *with* a displacement of 0, if it would otherwise not have one). -void xImpl_DwordShift::operator()(const xIndirectVoid &dest, const xRegister16or32or64 &from, const xRegisterCL & /* clreg */) const -{ - xOpWrite0F(from->GetPrefix16(), OpcodeBase + 1, from, dest); -} + if (info.Index.IsEmpty()) + { + EmitSibMagic(regfield, (void*)info.Displacement, extraRIPOffset); + return; + } + else + { + if (info.Index == rbp && displacement_size == 0) + displacement_size = 1; // forces [ebp] to be encoded as [ebp+0]! -void xImpl_DwordShift::operator()(const xIndirectVoid &dest, const xRegister16or32or64 &from, u8 shiftcnt) const -{ - if (shiftcnt != 0) - xOpWrite0F(from->GetPrefix16(), OpcodeBase, from, dest, shiftcnt); -} + ModRM(displacement_size, regfield, info.Index.Id & 7); + } + } + else + { + // In order to encode "just" index*scale (and no base), we have to encode + // it as a special [index*scale + displacement] form, which is done by + // specifying EBP as the base register and setting the displacement field + // to zero. (same as ModRm w/o SIB form above, basically, except the + // ModRm_UseDisp flag is specified in the SIB instead of the ModRM field). -const xImpl_Test xTEST = {}; + if (info.Base.IsEmpty()) + { + ModRM(0, regfield, ModRm_UseSib); + SibSB(info.Scale, info.Index.Id, Sib_UseDisp32); + xWrite(info.Displacement); + return; + } + else + { + if (info.Base == rbp && displacement_size == 0) + displacement_size = 1; // forces [ebp] to be encoded as [ebp+0]! -const xImpl_BitScan xBSF = {0xbc}; -const xImpl_BitScan xBSR = {0xbd}; + ModRM(displacement_size, regfield, ModRm_UseSib); + SibSB(info.Scale, info.Index.Id & 7, info.Base.Id & 7); + } + } -const xImpl_IncDec xINC = {false}; -const xImpl_IncDec xDEC = {true}; + if (displacement_size != 0) + { + if (displacement_size == 1) + xWrite(info.Displacement); + else + xWrite(info.Displacement); + } + } -const xImpl_DwordShift xSHLD = {0xa4}; -const xImpl_DwordShift xSHRD = {0xac}; + // Writes a ModRM byte for "Direct" register access forms, which is used for all + // instructions taking a form of [reg,reg]. + void EmitSibMagic(uint reg1, const xRegisterBase& reg2, int) + { + xWrite8((Mod_Direct << 6) | (reg1 << 3) | (reg2.Id & 7)); + } -////////////////////////////////////////////////////////////////////////////////////////// -// Push / Pop Emitters -// -// 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. + void EmitSibMagic(const xRegisterBase& reg1, const xRegisterBase& reg2, int) + { + xWrite8((Mod_Direct << 6) | ((reg1.Id & 7) << 3) | (reg2.Id & 7)); + } -__emitinline void xPOP(const xIndirectVoid &from) -{ - EmitRexImplicitlyWide(from); - xWrite8(0x8f); - EmitSibMagic(0, from); -} + void EmitSibMagic(const xRegisterBase& reg1, const void* src, int extraRIPOffset) + { + EmitSibMagic(reg1.Id & 7, src, extraRIPOffset); + } -__emitinline void xPUSH(const xIndirectVoid &from) -{ - EmitRexImplicitlyWide(from); - xWrite8(0xff); - EmitSibMagic(6, from); -} + void EmitSibMagic(const xRegisterBase& reg1, const xIndirectVoid& sib, int extraRIPOffset) + { + EmitSibMagic(reg1.Id & 7, sib, extraRIPOffset); + } -__fi void xPOP(xRegister32or64 from) { - EmitRexImplicitlyWide(from); - xWrite8(0x58 | (from->Id & 7)); -} + ////////////////////////////////////////////////////////////////////////////////////////// + __emitinline static void EmitRex(bool w, bool r, bool x, bool b) + { +#ifdef __M_X86_64 + const u8 rex = 0x40 | (w << 3) | (r << 2) | (x << 1) | (u8)b; + if (rex != 0x40) + xWrite8(rex); +#endif + } -__fi void xPUSH(u32 imm) -{ - if (is_s8(imm)) { - xWrite8(0x6a); - xWrite8(imm); - } else { - xWrite8(0x68); - xWrite32(imm); - } -} -__fi void xPUSH(xRegister32or64 from) { - EmitRexImplicitlyWide(from); - xWrite8(0x50 | (from->Id & 7)); -} + void EmitRex(uint regfield, const void* address) + { + pxAssert(0); + bool w = false; + bool r = false; + bool x = false; + bool b = false; + EmitRex(w, r, x, b); + } -// pushes the EFLAGS register onto the stack -__fi void xPUSHFD() { xWrite8(0x9C); } -// pops the EFLAGS register from the stack -__fi void xPOPFD() { xWrite8(0x9D); } + void EmitRex(uint regfield, const xIndirectVoid& info) + { + bool w = info.IsWide(); + bool r = false; + bool x = info.Index.IsExtended(); + bool b = info.Base.IsExtended(); + if (!NeedsSibMagic(info)) + { + b = x; + x = false; + } + EmitRex(w, r, x, b); + } + + void EmitRex(uint reg1, const xRegisterBase& reg2) + { + bool w = reg2.IsWide(); + bool r = false; + bool x = false; + bool b = reg2.IsExtended(); + EmitRex(w, r, x, b); + } + + void EmitRex(const xRegisterBase& reg1, const xRegisterBase& reg2) + { + bool w = reg1.IsWide(); + bool r = reg1.IsExtended(); + bool x = false; + bool b = reg2.IsExtended(); + EmitRex(w, r, x, b); + } + + void EmitRex(const xRegisterBase& reg1, const void* src) + { + pxAssert(0); //see fixme + bool w = reg1.IsWide(); + bool r = reg1.IsExtended(); + bool x = false; + bool b = false; // FIXME src.IsExtended(); + EmitRex(w, r, x, b); + } + + void EmitRex(const xRegisterBase& reg1, const xIndirectVoid& sib) + { + bool w = reg1.IsWide(); + bool r = reg1.IsExtended(); + bool x = sib.Index.IsExtended(); + bool b = sib.Base.IsExtended(); + if (!NeedsSibMagic(sib)) + { + b = x; + x = false; + } + EmitRex(w, r, x, b); + } + + // For use by instructions that are implicitly wide + void EmitRexImplicitlyWide(const xRegisterBase& reg) + { + bool w = false; + bool r = false; + bool x = false; + bool b = reg.IsExtended(); + EmitRex(w, r, x, b); + } + + void EmitRexImplicitlyWide(const xIndirectVoid& sib) + { + bool w = false; + bool r = false; + bool x = sib.Index.IsExtended(); + bool b = sib.Base.IsExtended(); + if (!NeedsSibMagic(sib)) + { + b = x; + x = false; + } + EmitRex(w, r, x, b); + } -////////////////////////////////////////////////////////////////////////////////////////// -// + // -------------------------------------------------------------------------------------- + // xSetPtr / xAlignPtr / xGetPtr / xAdvancePtr + // -------------------------------------------------------------------------------------- -__fi void xLEAVE() { xWrite8(0xC9); } -__fi void xRET() { xWrite8(0xC3); } -__fi void xCBW() { xWrite16(0x9866); } -__fi void xCWD() { xWrite8(0x98); } -__fi void xCDQ() { xWrite8(0x99); } -__fi void xCWDE() { xWrite8(0x98); } + // Assigns the current emitter buffer target address. + // This is provided instead of using x86Ptr directly, since we may in the future find + // a need to change the storage class system for the x86Ptr 'under the hood.' + __emitinline void xSetPtr(void* ptr) + { + x86Ptr = (u8*)ptr; + } -__fi void xLAHF() { xWrite8(0x9f); } -__fi void xSAHF() { xWrite8(0x9e); } + // Retrieves the current emitter buffer target address. + // This is provided instead of using x86Ptr directly, since we may in the future find + // a need to change the storage class system for the x86Ptr 'under the hood.' + __emitinline u8* xGetPtr() + { + return x86Ptr; + } -__fi void xSTC() { xWrite8(0xF9); } -__fi void xCLC() { xWrite8(0xF8); } + __emitinline void xAlignPtr(uint bytes) + { + // forward align + x86Ptr = (u8*)(((uptr)x86Ptr + bytes - 1) & ~(uptr)(bytes - 1)); + } -// NOP 1-byte -__fi void xNOP() { xWrite8(0x90); } + // Performs best-case alignment for the target CPU, for use prior to starting a new + // function. This is not meant to be used prior to jump targets, since it doesn't + // add padding (additionally, speed benefit from jump alignment is minimal, and often + // a loss). + __emitinline void xAlignCallTarget() + { + // Core2/i7 CPUs prefer unaligned addresses. Checking for SSSE3 is a decent filter. + // (also align in debug modes for disasm convenience) -__fi void xINT(u8 imm) -{ - if (imm == 3) - xWrite8(0xcc); - else { - xWrite8(0xcd); - xWrite8(imm); - } -} + if (IsDebugBuild || !x86caps.hasSupplementalStreamingSIMD3Extensions) + { + // - P4's and earlier prefer 16 byte alignment. + // - AMD Athlons and Phenoms prefer 8 byte alignment, but I don't have an easy + // heuristic for it yet. + // - AMD Phenom IIs are unknown (either prefer 8 byte, or unaligned). -__fi void xINTO() { xWrite8(0xce); } + xAlignPtr(16); + } + } -__emitinline void xBSWAP(const xRegister32or64 &to) -{ - xWrite8(0x0F); - xWrite8(0xC8 | to->Id); -} + __emitinline u8* xGetAlignedCallTarget() + { + xAlignCallTarget(); + return x86Ptr; + } -static __aligned16 u64 xmm_data[iREGCNT_XMM * 2]; + __emitinline void xAdvancePtr(uint bytes) + { + if (IsDevBuild) + { + // common debugger courtesy: advance with INT3 as filler. + for (uint i = 0; i < bytes; i++) + xWrite8(0xcc); + } + else + x86Ptr += bytes; + } -__emitinline void xStoreReg(const xRegisterSSE &src) -{ - xMOVDQA(ptr[&xmm_data[src.Id * 2]], src); -} + // -------------------------------------------------------------------------------------- + // xRegisterInt (method implementations) + // -------------------------------------------------------------------------------------- + xRegisterInt xRegisterInt::MatchSizeTo(xRegisterInt other) const + { + return other.GetOperandSize() == 1 ? xRegisterInt(xRegister8(*this)) : xRegisterInt(other.GetOperandSize(), Id); + } -__emitinline void xRestoreReg(const xRegisterSSE &dest) -{ - xMOVDQA(dest, ptr[&xmm_data[dest.Id * 2]]); -} + // -------------------------------------------------------------------------------------- + // xAddressReg (operator overloads) + // -------------------------------------------------------------------------------------- + xAddressVoid xAddressReg::operator+(const xAddressReg& right) const + { + pxAssertMsg(right.Id != -1 || Id != -1, "Uninitialized x86 register."); + return xAddressVoid(*this, right); + } + + xAddressVoid xAddressReg::operator+(sptr right) const + { + pxAssertMsg(Id != -1, "Uninitialized x86 register."); + return xAddressVoid(*this, right); + } + + xAddressVoid xAddressReg::operator+(const void* right) const + { + pxAssertMsg(Id != -1, "Uninitialized x86 register."); + return xAddressVoid(*this, (sptr)right); + } + + xAddressVoid xAddressReg::operator-(sptr right) const + { + pxAssertMsg(Id != -1, "Uninitialized x86 register."); + return xAddressVoid(*this, -right); + } + + xAddressVoid xAddressReg::operator-(const void* right) const + { + pxAssertMsg(Id != -1, "Uninitialized x86 register."); + return xAddressVoid(*this, -(sptr)right); + } + + xAddressVoid xAddressReg::operator*(int factor) const + { + pxAssertMsg(Id != -1, "Uninitialized x86 register."); + return xAddressVoid(xEmptyReg, *this, factor); + } + + xAddressVoid xAddressReg::operator<<(u32 shift) const + { + pxAssertMsg(Id != -1, "Uninitialized x86 register."); + return xAddressVoid(xEmptyReg, *this, 1 << shift); + } + + + // -------------------------------------------------------------------------------------- + // xAddressVoid (method implementations) + // -------------------------------------------------------------------------------------- + + xAddressVoid::xAddressVoid(const xAddressReg& base, const xAddressReg& index, int factor, sptr displacement) + { + Base = base; + Index = index; + Factor = factor; + Displacement = displacement; + + pxAssertMsg(base.Id != xRegId_Invalid, "Uninitialized x86 register."); + pxAssertMsg(index.Id != xRegId_Invalid, "Uninitialized x86 register."); + } + + xAddressVoid::xAddressVoid(const xAddressReg& index, sptr displacement) + { + Base = xEmptyReg; + Index = index; + Factor = 0; + Displacement = displacement; + + pxAssertMsg(index.Id != xRegId_Invalid, "Uninitialized x86 register."); + } + + xAddressVoid::xAddressVoid(sptr displacement) + { + Base = xEmptyReg; + Index = xEmptyReg; + Factor = 0; + Displacement = displacement; + } + + xAddressVoid::xAddressVoid(const void* displacement) + { + Base = xEmptyReg; + Index = xEmptyReg; + Factor = 0; + Displacement = (sptr)displacement; + } + + xAddressVoid& xAddressVoid::Add(const xAddressReg& src) + { + if (src == Index) + { + Factor++; + } + else if (src == Base) + { + // Compound the existing register reference into the Index/Scale pair. + Base = xEmptyReg; + + if (src == Index) + Factor++; + else + { + pxAssertDev(Index.IsEmpty(), "x86Emitter: Only one scaled index register is allowed in an address modifier."); + Index = src; + Factor = 2; + } + } + else if (Base.IsEmpty()) + Base = src; + else if (Index.IsEmpty()) + Index = src; + else + pxAssumeDev(false, L"x86Emitter: address modifiers cannot have more than two index registers."); // oops, only 2 regs allowed per ModRm! + + return *this; + } + + xAddressVoid& xAddressVoid::Add(const xAddressVoid& src) + { + Add(src.Base); + Add(src.Displacement); + + // If the factor is 1, we can just treat index like a base register also. + if (src.Factor == 1) + { + Add(src.Index); + } + else if (Index.IsEmpty()) + { + Index = src.Index; + Factor = src.Factor; + } + else if (Index == src.Index) + { + Factor += src.Factor; + } + else + pxAssumeDev(false, L"x86Emitter: address modifiers cannot have more than two index registers."); // oops, only 2 regs allowed per ModRm! + + return *this; + } + + xIndirectVoid::xIndirectVoid(const xAddressVoid& src) + { + Base = src.Base; + Index = src.Index; + Scale = src.Factor; + Displacement = src.Displacement; + + Reduce(); + } + + xIndirectVoid::xIndirectVoid(sptr disp) + { + Base = xEmptyReg; + Index = xEmptyReg; + Scale = 0; + Displacement = disp; + + // no reduction necessary :D + } + + xIndirectVoid::xIndirectVoid(xAddressReg base, xAddressReg index, int scale, sptr displacement) + { + Base = base; + Index = index; + Scale = scale; + Displacement = displacement; + + Reduce(); + } + + // Generates a 'reduced' ModSib form, which has valid Base, Index, and Scale values. + // Necessary because by default ModSib compounds registers into Index when possible. + // + // If the ModSib is in illegal form ([Base + Index*5] for example) then an assertion + // followed by an InvalidParameter Exception will be tossed around in haphazard + // fashion. + // + // Optimization Note: Currently VC does a piss poor job of inlining this, even though + // constant propagation *should* resove it to little or no code (VC's constprop fails + // on C++ class initializers). There is a work around [using array initializers instead] + // but it's too much trouble for code that isn't performance critical anyway. + // And, with luck, maybe VC10 will optimize it better and make it a non-issue. :D + // + void xIndirectVoid::Reduce() + { + if (Index.IsStackPointer()) + { + // esp cannot be encoded as the index, so move it to the Base, if possible. + // note: intentionally leave index assigned to esp also (generates correct + // encoding later, since ESP cannot be encoded 'alone') + + pxAssert(Scale == 0); // esp can't have an index modifier! + pxAssert(Base.IsEmpty()); // base must be empty or else! + + Base = Index; + return; + } + + // If no index reg, then load the base register into the index slot. + if (Index.IsEmpty()) + { + Index = Base; + Scale = 0; + if (!Base.IsStackPointer()) // prevent ESP from being encoded 'alone' + Base = xEmptyReg; + return; + } + + // The Scale has a series of valid forms, all shown here: + + switch (Scale) + { + case 0: + break; + case 1: + Scale = 0; + break; + case 2: + Scale = 1; + break; + + case 3: // becomes [reg*2+reg] + pxAssertDev(Base.IsEmpty(), "Cannot scale an Index register by 3 when Base is not empty!"); + Base = Index; + Scale = 1; + break; + + case 4: + Scale = 2; + break; + + case 5: // becomes [reg*4+reg] + pxAssertDev(Base.IsEmpty(), "Cannot scale an Index register by 5 when Base is not empty!"); + Base = Index; + Scale = 2; + break; + + case 6: // invalid! + pxAssumeDev(false, "x86 asm cannot scale a register by 6."); + break; + + case 7: // so invalid! + pxAssumeDev(false, "x86 asm cannot scale a register by 7."); + break; + + case 8: + Scale = 3; + break; + case 9: // becomes [reg*8+reg] + pxAssertDev(Base.IsEmpty(), "Cannot scale an Index register by 9 when Base is not empty!"); + Base = Index; + Scale = 3; + break; + + jNO_DEFAULT + } + } + + xIndirectVoid& xIndirectVoid::Add(sptr imm) + { + Displacement += imm; + return *this; + } + + // ------------------------------------------------------------------------ + // Internal implementation of EmitSibMagic which has been custom tailored + // to optimize special forms of the Lea instructions accordingly, such + // as when a LEA can be replaced with a "MOV reg,imm" or "MOV reg,reg". + // + // preserve_flags - set to ture to disable use of SHL on [Index*Base] forms + // of LEA, which alters flags states. + // + static void EmitLeaMagic(const xRegisterInt& to, const xIndirectVoid& src, bool preserve_flags) + { + int displacement_size = (src.Displacement == 0) ? 0 : + ((src.IsByteSizeDisp()) ? 1 : 2); + + // See EmitSibMagic for commenting on SIB encoding. + + if (!NeedsSibMagic(src) && src.Displacement == (s32)src.Displacement) + { + // LEA Land: means we have either 1-register encoding or just an offset. + // offset is encodable as an immediate MOV, and a register is encodable + // as a register MOV. + + if (src.Index.IsEmpty()) + { + xMOV(to, src.Displacement); + return; + } + else if (displacement_size == 0) + { + _xMovRtoR(to, src.Index.MatchSizeTo(to)); + return; + } + else if (!preserve_flags) + { + // encode as MOV and ADD combo. Make sure to use the immediate on the + // ADD since it can encode as an 8-bit sign-extended value. + + _xMovRtoR(to, src.Index.MatchSizeTo(to)); + xADD(to, src.Displacement); + return; + } + } + else + { + if (src.Base.IsEmpty()) + { + if (!preserve_flags && (displacement_size == 0)) + { + // Encode [Index*Scale] as a combination of Mov and Shl. + // This is more efficient because of the bloated LEA format which requires + // a 32 bit displacement, and the compact nature of the alternative. + // + // (this does not apply to older model P4s with the broken barrel shifter, + // but we currently aren't optimizing for that target anyway). + + _xMovRtoR(to, src.Index); + xSHL(to, src.Scale); + return; + } + } + else + { + if (src.Scale == 0) + { + if (!preserve_flags) + { + if (src.Index == rsp) + { + // ESP is not encodable as an index (ix86 ignores it), thus: + _xMovRtoR(to, src.Base.MatchSizeTo(to)); // will do the trick! + if (src.Displacement) + xADD(to, src.Displacement); + return; + } + else if (src.Displacement == 0) + { + _xMovRtoR(to, src.Base.MatchSizeTo(to)); + _g1_EmitOp(G1Type_ADD, to, src.Index.MatchSizeTo(to)); + return; + } + } + else if ((src.Index == rsp) && (src.Displacement == 0)) + { + // special case handling of ESP as Index, which is replaceable with + // a single MOV even when preserve_flags is set! :D + + _xMovRtoR(to, src.Base.MatchSizeTo(to)); + return; + } + } + } + } + + xOpWrite(0, 0x8d, to, src); + } + + __emitinline void xLEA(xRegister64 to, const xIndirectVoid& src, bool preserve_flags) + { + EmitLeaMagic(to, src, preserve_flags); + } + + __emitinline void xLEA(xRegister32 to, const xIndirectVoid& src, bool preserve_flags) + { + EmitLeaMagic(to, src, preserve_flags); + } + + __emitinline void xLEA(xRegister16 to, const xIndirectVoid& src, bool preserve_flags) + { + xWrite8(0x66); + EmitLeaMagic(to, src, preserve_flags); + } + + __emitinline u32* xLEA_Writeback(xAddressReg to) + { +#ifdef __M_X86_64 + xOpWrite(0, 0x8d, to, ptr[(void*)(0xdcdcdcd + (uptr)xGetPtr() + 7)]); +#else + xOpAccWrite(0, 0xb8 | to.Id, 0, to); + xWrite32(0xcdcdcdcd); +#endif + return (u32*)xGetPtr() - 1; + } + + // ===================================================================================================== + // TEST / INC / DEC + // ===================================================================================================== + void xImpl_Test::operator()(const xRegisterInt& to, const xRegisterInt& from) const + { + pxAssert(to.GetOperandSize() == from.GetOperandSize()); + xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0x84 : 0x85, from, to); + } + + void xImpl_Test::operator()(const xIndirect64orLess& dest, int imm) const + { + xOpWrite(dest.GetPrefix16(), dest.Is8BitOp() ? 0xf6 : 0xf7, 0, dest, dest.GetImmSize()); + dest.xWriteImm(imm); + } + + void xImpl_Test::operator()(const xRegisterInt& to, int imm) const + { + if (to.IsAccumulator()) + { + xOpAccWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xa8 : 0xa9, 0, to); + } + else + { + xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xf6 : 0xf7, 0, to); + } + to.xWriteImm(imm); + } + + void xImpl_BitScan::operator()(const xRegister16or32or64& to, const xRegister16or32or64& from) const + { + pxAssert(to->GetOperandSize() == from->GetOperandSize()); + xOpWrite0F(from->GetPrefix16(), Opcode, to, from); + } + void xImpl_BitScan::operator()(const xRegister16or32or64& to, const xIndirectVoid& sibsrc) const + { + xOpWrite0F(to->GetPrefix16(), Opcode, to, sibsrc); + } + + void xImpl_IncDec::operator()(const xRegisterInt& to) const + { + if (to.Is8BitOp()) + { + u8 regfield = isDec ? 1 : 0; + xOpWrite(to.GetPrefix16(), 0xfe, regfield, to); + } + else + { +#ifdef __M_X86_64 + xOpWrite(to.GetPrefix16(), 0xff, isDec ? 1 : 0, to); +#else + to.prefix16(); + xWrite8((isDec ? 0x48 : 0x40) | to.Id); +#endif + } + } + + void xImpl_IncDec::operator()(const xIndirect64orLess& to) const + { + to.prefix16(); + xWrite8(to.Is8BitOp() ? 0xfe : 0xff); + EmitSibMagic(isDec ? 1 : 0, to); + } + + void xImpl_DwordShift::operator()(const xRegister16or32or64& to, const xRegister16or32or64& from, const xRegisterCL& /* clreg */) const + { + pxAssert(to->GetOperandSize() == from->GetOperandSize()); + xOpWrite0F(from->GetPrefix16(), OpcodeBase + 1, to, from); + } + + void xImpl_DwordShift::operator()(const xRegister16or32or64& to, const xRegister16or32or64& from, u8 shiftcnt) const + { + pxAssert(to->GetOperandSize() == from->GetOperandSize()); + if (shiftcnt != 0) + xOpWrite0F(from->GetPrefix16(), OpcodeBase, to, from, shiftcnt); + } + + void xImpl_DwordShift::operator()(const xIndirectVoid& dest, const xRegister16or32or64& from, const xRegisterCL& /* clreg */) const + { + xOpWrite0F(from->GetPrefix16(), OpcodeBase + 1, from, dest); + } + + void xImpl_DwordShift::operator()(const xIndirectVoid& dest, const xRegister16or32or64& from, u8 shiftcnt) const + { + if (shiftcnt != 0) + xOpWrite0F(from->GetPrefix16(), OpcodeBase, from, dest, shiftcnt); + } + + const xImpl_Test xTEST = {}; + + const xImpl_BitScan xBSF = {0xbc}; + const xImpl_BitScan xBSR = {0xbd}; + + const xImpl_IncDec xINC = {false}; + const xImpl_IncDec xDEC = {true}; + + const xImpl_DwordShift xSHLD = {0xa4}; + const xImpl_DwordShift xSHRD = {0xac}; + + ////////////////////////////////////////////////////////////////////////////////////////// + // Push / Pop Emitters + // + // 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. + + __emitinline void xPOP(const xIndirectVoid& from) + { + EmitRexImplicitlyWide(from); + xWrite8(0x8f); + EmitSibMagic(0, from); + } + + __emitinline void xPUSH(const xIndirectVoid& from) + { + EmitRexImplicitlyWide(from); + xWrite8(0xff); + EmitSibMagic(6, from); + } + + __fi void xPOP(xRegister32or64 from) + { + EmitRexImplicitlyWide(from); + xWrite8(0x58 | (from->Id & 7)); + } + + __fi void xPUSH(u32 imm) + { + if (is_s8(imm)) + { + xWrite8(0x6a); + xWrite8(imm); + } + else + { + xWrite8(0x68); + xWrite32(imm); + } + } + __fi void xPUSH(xRegister32or64 from) + { + EmitRexImplicitlyWide(from); + xWrite8(0x50 | (from->Id & 7)); + } + + // pushes the EFLAGS register onto the stack + __fi void xPUSHFD() { xWrite8(0x9C); } + // pops the EFLAGS register from the stack + __fi void xPOPFD() { xWrite8(0x9D); } + + + ////////////////////////////////////////////////////////////////////////////////////////// + // + + __fi void xLEAVE() { xWrite8(0xC9); } + __fi void xRET() { xWrite8(0xC3); } + __fi void xCBW() { xWrite16(0x9866); } + __fi void xCWD() { xWrite8(0x98); } + __fi void xCDQ() { xWrite8(0x99); } + __fi void xCWDE() { xWrite8(0x98); } + + __fi void xLAHF() { xWrite8(0x9f); } + __fi void xSAHF() { xWrite8(0x9e); } + + __fi void xSTC() { xWrite8(0xF9); } + __fi void xCLC() { xWrite8(0xF8); } + + // NOP 1-byte + __fi void xNOP() { xWrite8(0x90); } + + __fi void xINT(u8 imm) + { + if (imm == 3) + xWrite8(0xcc); + else + { + xWrite8(0xcd); + xWrite8(imm); + } + } + + __fi void xINTO() { xWrite8(0xce); } + + __emitinline void xBSWAP(const xRegister32or64& to) + { + xWrite8(0x0F); + xWrite8(0xC8 | to->Id); + } + + static __aligned16 u64 xmm_data[iREGCNT_XMM * 2]; + + __emitinline void xStoreReg(const xRegisterSSE& src) + { + xMOVDQA(ptr[&xmm_data[src.Id * 2]], src); + } + + __emitinline void xRestoreReg(const xRegisterSSE& dest) + { + xMOVDQA(dest, ptr[&xmm_data[dest.Id * 2]]); + } ////////////////////////////////////////////////////////////////////////////////////////// // Helper object to handle ABI frame @@ -1151,136 +1218,154 @@ __emitinline void xRestoreReg(const xRegisterSSE &dest) #endif -static void stackAlign(int offset, bool moveDown) { - int needed = (16 - (offset % 16)) % 16; - if (moveDown) { - needed = -needed; - } - ALIGN_STACK(needed); -} + static void stackAlign(int offset, bool moveDown) + { + int needed = (16 - (offset % 16)) % 16; + if (moveDown) + { + needed = -needed; + } + ALIGN_STACK(needed); + } -xScopedStackFrame::xScopedStackFrame(bool base_frame, bool save_base_pointer, int offset) -{ - m_base_frame = base_frame; - m_save_base_pointer = save_base_pointer; - m_offset = offset; + xScopedStackFrame::xScopedStackFrame(bool base_frame, bool save_base_pointer, int offset) + { + m_base_frame = base_frame; + m_save_base_pointer = save_base_pointer; + m_offset = offset; - m_offset += sizeof(void*); // Call stores the return address (4 bytes) + m_offset += sizeof(void*); // Call stores the return address (4 bytes) - // Note rbp can surely be optimized in 64 bits - if (m_base_frame) { - xPUSH(rbp); - xMOV(rbp, rsp); - m_offset += sizeof(void*); - } else if (m_save_base_pointer) { - xPUSH(rbp); - m_offset += sizeof(void*); - } + // Note rbp can surely be optimized in 64 bits + if (m_base_frame) + { + xPUSH(rbp); + xMOV(rbp, rsp); + m_offset += sizeof(void*); + } + else if (m_save_base_pointer) + { + xPUSH(rbp); + m_offset += sizeof(void*); + } #ifdef __M_X86_64 - xPUSH(rbx); - xPUSH(r12); - xPUSH(r13); - xPUSH(r14); - xPUSH(r15); - m_offset += 40; + xPUSH(rbx); + xPUSH(r12); + xPUSH(r13); + xPUSH(r14); + xPUSH(r15); + m_offset += 40; #ifdef _WIN32 - xPUSH(rdi); - xPUSH(rsi); - xSUB(rsp, 32); // Windows calling convention specifies additional space for the callee to spill registers - m_offset += 48; + xPUSH(rdi); + xPUSH(rsi); + xSUB(rsp, 32); // Windows calling convention specifies additional space for the callee to spill registers + m_offset += 48; #endif #else - // Save the register context - xPUSH(edi); - xPUSH(esi); - xPUSH(ebx); - m_offset += 12; + // Save the register context + xPUSH(edi); + xPUSH(esi); + xPUSH(ebx); + m_offset += 12; #endif - stackAlign(m_offset, true); -} + stackAlign(m_offset, true); + } -xScopedStackFrame::~xScopedStackFrame() -{ - stackAlign(m_offset, false); + xScopedStackFrame::~xScopedStackFrame() + { + stackAlign(m_offset, false); #ifdef __M_X86_64 - // Restore the register context + // Restore the register context #ifdef _WIN32 - xADD(rsp, 32); - xPOP(rsi); - xPOP(rdi); + xADD(rsp, 32); + xPOP(rsi); + xPOP(rdi); #endif - xPOP(r15); - xPOP(r14); - xPOP(r13); - xPOP(r12); - xPOP(rbx); + xPOP(r15); + xPOP(r14); + xPOP(r13); + xPOP(r12); + xPOP(rbx); #else - // Restore the register context - xPOP(ebx); - xPOP(esi); - xPOP(edi); + // Restore the register context + xPOP(ebx); + xPOP(esi); + xPOP(edi); #endif - // Destroy the frame - if (m_base_frame) { - xLEAVE(); - } else if (m_save_base_pointer) { - xPOP(rbp); - } -} + // Destroy the frame + if (m_base_frame) + { + xLEAVE(); + } + else if (m_save_base_pointer) + { + xPOP(rbp); + } + } -xScopedSavedRegisters::xScopedSavedRegisters(std::initializer_list> regs) - : regs(regs) -{ - for (auto reg : regs) - { - const xAddressReg& regRef = reg; - xPUSH(regRef); - } - stackAlign(regs.size() * wordsize, true); -} + xScopedSavedRegisters::xScopedSavedRegisters(std::initializer_list> regs) + : regs(regs) + { + for (auto reg : regs) + { + const xAddressReg& regRef = reg; + xPUSH(regRef); + } + stackAlign(regs.size() * wordsize, true); + } -xScopedSavedRegisters::~xScopedSavedRegisters() { - stackAlign(regs.size() * wordsize, false); - for (auto it = regs.rbegin(); it < regs.rend(); ++it) { - const xAddressReg& regRef = *it; - xPOP(regRef); - } -} + xScopedSavedRegisters::~xScopedSavedRegisters() + { + stackAlign(regs.size() * wordsize, false); + for (auto it = regs.rbegin(); it < regs.rend(); ++it) + { + const xAddressReg& regRef = *it; + xPOP(regRef); + } + } -xAddressVoid xComplexAddress(const xAddressReg& tmpRegister, void *base, const xAddressVoid& offset) { - if ((sptr)base == (s32)(sptr)base) { - return offset + base; - } else { - xLEA(tmpRegister, ptr[base]); - return offset + tmpRegister; - } -} + xAddressVoid xComplexAddress(const xAddressReg& tmpRegister, void* base, const xAddressVoid& offset) + { + if ((sptr)base == (s32)(sptr)base) + { + return offset + base; + } + else + { + xLEA(tmpRegister, ptr[base]); + return offset + tmpRegister; + } + } -void xLoadFarAddr(const xAddressReg& dst, void *addr) { + void xLoadFarAddr(const xAddressReg& dst, void* addr) + { #ifdef __M_X86_64 - sptr iaddr = (sptr)addr; - sptr rip = (sptr)xGetPtr() + 7; // LEA will be 7 bytes - sptr disp = iaddr - rip; - if (disp == (s32)disp) { - xLEA(dst, ptr[addr]); - } else { - xMOV64(dst, iaddr); - } + sptr iaddr = (sptr)addr; + sptr rip = (sptr)xGetPtr() + 7; // LEA will be 7 bytes + sptr disp = iaddr - rip; + if (disp == (s32)disp) + { + xLEA(dst, ptr[addr]); + } + else + { + xMOV64(dst, iaddr); + } #else - xMOV(dst, (sptr)addr); + xMOV(dst, (sptr)addr); #endif -} + } } // End namespace x86Emitter diff --git a/common/emitter/x86types.h b/common/emitter/x86types.h index eda149ddba..b10895afaa 100644 --- a/common/emitter/x86types.h +++ b/common/emitter/x86types.h @@ -26,10 +26,11 @@ static const uint iREGCNT_XMM = 8; static const uint iREGCNT_GPR = 8; #endif -enum XMMSSEType { - XMMT_INT = 0, // integer (sse2 only) - XMMT_FPS = 1, // floating point - //XMMT_FPD = 3, // double +enum XMMSSEType +{ + XMMT_INT = 0, // integer (sse2 only) + XMMT_FPS = 1, // floating point + //XMMT_FPD = 3, // double }; // -------------------------------------------------------------------------------------- @@ -62,29 +63,29 @@ enum XMMSSEType { #endif #endif -extern __tls_emit u8 *x86Ptr; +extern __tls_emit u8* x86Ptr; extern __tls_emit XMMSSEType g_xmmtypes[iREGCNT_XMM]; namespace x86Emitter { -extern void xWrite8(u8 val); -extern void xWrite16(u16 val); -extern void xWrite32(u32 val); -extern void xWrite64(u64 val); + extern void xWrite8(u8 val); + extern void xWrite16(u16 val); + extern void xWrite32(u32 val); + extern void xWrite64(u64 val); -extern const char *xGetRegName(int regid, int operandSize); + extern const char* xGetRegName(int regid, int operandSize); -//------------------------------------------------------------------ -// templated version of is_s8 is required, so that u16's get correct sign extension treatment. -template -static __fi bool is_s8(T imm) -{ - return (s8)imm == (s32)imm; -} + //------------------------------------------------------------------ + // templated version of is_s8 is required, so that u16's get correct sign extension treatment. + template + static __fi bool is_s8(T imm) + { + return (s8)imm == (s32)imm; + } -template -void xWrite(T val); + template + void xWrite(T val); // -------------------------------------------------------------------------------------- // ALWAYS_USE_MOVAPS [define] / AlwaysUseMovaps [const] @@ -98,9 +99,9 @@ void xWrite(T val); #define ALWAYS_USE_MOVAPS #ifdef ALWAYS_USE_MOVAPS -static const bool AlwaysUseMovaps = true; + static const bool AlwaysUseMovaps = true; #else -static const bool AlwaysUseMovaps = false; + static const bool AlwaysUseMovaps = false; #endif // -------------------------------------------------------------------------------------- @@ -126,478 +127,494 @@ static const bool AlwaysUseMovaps = false; #define __emitinline __fi #endif -// ModRM 'mod' field enumeration. Provided mostly for reference: -enum ModRm_ModField { - Mod_NoDisp = 0, // effective address operation with no displacement, in the form of [reg] (or uses special Disp32-only encoding in the case of [ebp] form) - Mod_Disp8, // effective address operation with 8 bit displacement, in the form of [reg+disp8] - Mod_Disp32, // effective address operation with 32 bit displacement, in the form of [reg+disp32], - Mod_Direct, // direct reg/reg operation -}; + // ModRM 'mod' field enumeration. Provided mostly for reference: + enum ModRm_ModField + { + Mod_NoDisp = 0, // effective address operation with no displacement, in the form of [reg] (or uses special Disp32-only encoding in the case of [ebp] form) + Mod_Disp8, // effective address operation with 8 bit displacement, in the form of [reg+disp8] + Mod_Disp32, // effective address operation with 32 bit displacement, in the form of [reg+disp32], + Mod_Direct, // direct reg/reg operation + }; -// ---------------------------------------------------------------------------- -// JccComparisonType - enumerated possibilities for inspired code branching! -// -enum JccComparisonType { - Jcc_Unknown = -2, - Jcc_Unconditional = -1, - Jcc_Overflow = 0x0, - Jcc_NotOverflow = 0x1, - Jcc_Below = 0x2, - Jcc_Carry = 0x2, - Jcc_AboveOrEqual = 0x3, - Jcc_NotCarry = 0x3, - Jcc_Zero = 0x4, - Jcc_Equal = 0x4, - Jcc_NotZero = 0x5, - Jcc_NotEqual = 0x5, - Jcc_BelowOrEqual = 0x6, - Jcc_Above = 0x7, - Jcc_Signed = 0x8, - Jcc_Unsigned = 0x9, - Jcc_ParityEven = 0xa, - Jcc_ParityOdd = 0xb, - Jcc_Less = 0xc, - Jcc_GreaterOrEqual = 0xd, - Jcc_LessOrEqual = 0xe, - Jcc_Greater = 0xf, -}; + // ---------------------------------------------------------------------------- + // JccComparisonType - enumerated possibilities for inspired code branching! + // + enum JccComparisonType + { + Jcc_Unknown = -2, + Jcc_Unconditional = -1, + Jcc_Overflow = 0x0, + Jcc_NotOverflow = 0x1, + Jcc_Below = 0x2, + Jcc_Carry = 0x2, + Jcc_AboveOrEqual = 0x3, + Jcc_NotCarry = 0x3, + Jcc_Zero = 0x4, + Jcc_Equal = 0x4, + Jcc_NotZero = 0x5, + Jcc_NotEqual = 0x5, + Jcc_BelowOrEqual = 0x6, + Jcc_Above = 0x7, + Jcc_Signed = 0x8, + Jcc_Unsigned = 0x9, + Jcc_ParityEven = 0xa, + Jcc_ParityOdd = 0xb, + Jcc_Less = 0xc, + Jcc_GreaterOrEqual = 0xd, + Jcc_LessOrEqual = 0xe, + Jcc_Greater = 0xf, + }; -// Not supported yet: -//E3 cb JECXZ rel8 Jump short if ECX register is 0. + // Not supported yet: + //E3 cb JECXZ rel8 Jump short if ECX register is 0. -// ---------------------------------------------------------------------------- -// SSE2_ComparisonType - enumerated possibilities for SIMD data comparison! -// -enum SSE2_ComparisonType { - SSE2_Equal = 0, - SSE2_Less, - SSE2_LessOrEqual, - SSE2_Unordered, - SSE2_NotEqual, - SSE2_NotLess, - SSE2_NotLessOrEqual, - SSE2_Ordered -}; + // ---------------------------------------------------------------------------- + // SSE2_ComparisonType - enumerated possibilities for SIMD data comparison! + // + enum SSE2_ComparisonType + { + SSE2_Equal = 0, + SSE2_Less, + SSE2_LessOrEqual, + SSE2_Unordered, + SSE2_NotEqual, + SSE2_NotLess, + SSE2_NotLessOrEqual, + SSE2_Ordered + }; -static const int ModRm_UseSib = 4; // same index value as ESP (used in RM field) -static const int ModRm_UseDisp32 = 5; // same index value as EBP (used in Mod field) -static const int Sib_EIZ = 4; // same index value as ESP (used in Index field) -static const int Sib_UseDisp32 = 5; // same index value as EBP (used in Base field) + static const int ModRm_UseSib = 4; // same index value as ESP (used in RM field) + static const int ModRm_UseDisp32 = 5; // same index value as EBP (used in Mod field) + static const int Sib_EIZ = 4; // same index value as ESP (used in Index field) + static const int Sib_UseDisp32 = 5; // same index value as EBP (used in Base field) -extern void xSetPtr(void *ptr); -extern void xAlignPtr(uint bytes); -extern void xAdvancePtr(uint bytes); -extern void xAlignCallTarget(); + extern void xSetPtr(void* ptr); + extern void xAlignPtr(uint bytes); + extern void xAdvancePtr(uint bytes); + extern void xAlignCallTarget(); -extern u8 *xGetPtr(); -extern u8 *xGetAlignedCallTarget(); + extern u8* xGetPtr(); + extern u8* xGetAlignedCallTarget(); -extern JccComparisonType xInvertCond(JccComparisonType src); + extern JccComparisonType xInvertCond(JccComparisonType src); -class xAddressVoid; + class xAddressVoid; -// -------------------------------------------------------------------------------------- -// OperandSizedObject -// -------------------------------------------------------------------------------------- -class OperandSizedObject -{ -protected: - uint _operandSize = 0; - OperandSizedObject() = default; - OperandSizedObject(uint operandSize) - : _operandSize(operandSize) - { - } -public: - uint GetOperandSize() const { - pxAssertDev(_operandSize != 0, "Attempted to use operand size of uninitialized or void object"); - return _operandSize; - } + // -------------------------------------------------------------------------------------- + // OperandSizedObject + // -------------------------------------------------------------------------------------- + class OperandSizedObject + { + protected: + uint _operandSize = 0; + OperandSizedObject() = default; + OperandSizedObject(uint operandSize) + : _operandSize(operandSize) + { + } - bool Is8BitOp() const { return GetOperandSize() == 1; } - u8 GetPrefix16() const { return GetOperandSize() == 2 ? 0x66 : 0; } - void prefix16() const - { - if (GetOperandSize() == 2) - xWrite8(0x66); - } + public: + uint GetOperandSize() const + { + pxAssertDev(_operandSize != 0, "Attempted to use operand size of uninitialized or void object"); + return _operandSize; + } - int GetImmSize() const { - switch (GetOperandSize()) { - case 1: return 1; - case 2: return 2; - case 4: return 4; - case 8: return 4; // Only mov's take 64-bit immediates - jNO_DEFAULT - } - return 0; - } + bool Is8BitOp() const { return GetOperandSize() == 1; } + u8 GetPrefix16() const { return GetOperandSize() == 2 ? 0x66 : 0; } + void prefix16() const + { + if (GetOperandSize() == 2) + xWrite8(0x66); + } - void xWriteImm(int imm) const - { - switch (GetImmSize()) { - case 1: - xWrite8(imm); - break; - case 2: - xWrite16(imm); - break; - case 4: - xWrite32(imm); - break; + int GetImmSize() const + { + switch (GetOperandSize()) + { + case 1: + return 1; + case 2: + return 2; + case 4: + return 4; + case 8: + return 4; // Only mov's take 64-bit immediates + jNO_DEFAULT + } + return 0; + } - jNO_DEFAULT - } - } -}; + void xWriteImm(int imm) const + { + switch (GetImmSize()) + { + case 1: + xWrite8(imm); + break; + case 2: + xWrite16(imm); + break; + case 4: + xWrite32(imm); + break; -// Represents an unused or "empty" register assignment. If encountered by the emitter, this -// will be ignored (in some cases it is disallowed and generates an assertion) -static const int xRegId_Empty = -1; + jNO_DEFAULT + } + } + }; -// Represents an invalid or uninitialized register. If this is encountered by the emitter it -// will generate an assertion. -static const int xRegId_Invalid = -2; + // Represents an unused or "empty" register assignment. If encountered by the emitter, this + // will be ignored (in some cases it is disallowed and generates an assertion) + static const int xRegId_Empty = -1; -// -------------------------------------------------------------------------------------- -// xRegisterBase - type-unsafe x86 register representation. -// -------------------------------------------------------------------------------------- -// Unless doing some fundamental stuff, use the friendly xRegister32/16/8 and xRegisterSSE -// instead, which are built using this class and provide strict register type safety when -// passed into emitter instructions. -// -class xRegisterBase : public OperandSizedObject -{ -protected: - xRegisterBase(uint operandSize, int regId) - : OperandSizedObject(operandSize), Id(regId) - { - // Note: to avoid tons of ifdef, the 32 bits build will instantiate - // all 16x64 bits registers. - pxAssert((Id >= xRegId_Empty) && (Id < 16)); - } -public: - int Id; + // Represents an invalid or uninitialized register. If this is encountered by the emitter it + // will generate an assertion. + static const int xRegId_Invalid = -2; - xRegisterBase() - : OperandSizedObject(0), Id(xRegId_Invalid) - { - } + // -------------------------------------------------------------------------------------- + // xRegisterBase - type-unsafe x86 register representation. + // -------------------------------------------------------------------------------------- + // Unless doing some fundamental stuff, use the friendly xRegister32/16/8 and xRegisterSSE + // instead, which are built using this class and provide strict register type safety when + // passed into emitter instructions. + // + class xRegisterBase : public OperandSizedObject + { + protected: + xRegisterBase(uint operandSize, int regId) + : OperandSizedObject(operandSize) + , Id(regId) + { + // Note: to avoid tons of ifdef, the 32 bits build will instantiate + // all 16x64 bits registers. + pxAssert((Id >= xRegId_Empty) && (Id < 16)); + } - bool IsEmpty() const { return Id < 0; } - bool IsInvalid() const { return Id == xRegId_Invalid; } - bool IsExtended() const { return Id > 7; } // Register 8-15 need an extra bit to be selected - bool IsMem() const { return false; } - bool IsReg() const { return true; } + public: + int Id; - // Returns true if the register is a valid accumulator: Eax, Ax, Al, XMM0. - bool IsAccumulator() const { return Id == 0; } + xRegisterBase() + : OperandSizedObject(0) + , Id(xRegId_Invalid) + { + } - // IsSIMD: returns true if the register is a valid XMM register. - bool IsSIMD() const { return GetOperandSize() == 16; } + bool IsEmpty() const { return Id < 0; } + bool IsInvalid() const { return Id == xRegId_Invalid; } + bool IsExtended() const { return Id > 7; } // Register 8-15 need an extra bit to be selected + bool IsMem() const { return false; } + bool IsReg() const { return true; } + + // Returns true if the register is a valid accumulator: Eax, Ax, Al, XMM0. + bool IsAccumulator() const { return Id == 0; } + + // IsSIMD: returns true if the register is a valid XMM register. + bool IsSIMD() const { return GetOperandSize() == 16; } // IsWide: return true if the register is 64 bits (requires a wide op on the rex prefix) #ifdef __M_X86_64 - bool IsWide() const - { - return GetOperandSize() == 8; - } + bool IsWide() const + { + return GetOperandSize() == 8; + } #else - bool IsWide() const - { - return false; - } // no 64 bits GPR + bool IsWide() const + { + return false; + } // no 64 bits GPR #endif - // return true if the register is a valid YMM register - bool IsWideSIMD() const { return GetOperandSize() == 32; } + // return true if the register is a valid YMM register + bool IsWideSIMD() const { return GetOperandSize() == 32; } - // Diagnostics -- returns a string representation of this register. Return string - // is a valid non-null string for any Id, valid or invalid. No assertions are generated. - const char *GetName(); - int GetId() const { return Id; } -}; + // Diagnostics -- returns a string representation of this register. Return string + // is a valid non-null string for any Id, valid or invalid. No assertions are generated. + const char* GetName(); + int GetId() const { return Id; } + }; -class xRegisterInt : public xRegisterBase -{ - typedef xRegisterBase _parent; + class xRegisterInt : public xRegisterBase + { + typedef xRegisterBase _parent; -protected: - explicit xRegisterInt(uint operandSize, int regId) - : _parent(operandSize, regId) - { - } -public: - xRegisterInt() = default; + protected: + explicit xRegisterInt(uint operandSize, int regId) + : _parent(operandSize, regId) + { + } - /// IDs in [4, 8) are h registers in 8-bit - int isIDSameInAllSizes() const - { - return Id < 4 || Id >= 8; - } + public: + xRegisterInt() = default; - /// Checks if mapping the ID directly would be a good idea - bool canMapIDTo(int otherSize) const - { - if ((otherSize == 1) == (GetOperandSize() == 1)) - return true; - return isIDSameInAllSizes(); - } + /// IDs in [4, 8) are h registers in 8-bit + int isIDSameInAllSizes() const + { + return Id < 4 || Id >= 8; + } - /// Get a non-wide version of the register (for use with e.g. mov, where `mov eax, 3` and `mov rax, 3` are functionally identical but `mov eax, 3` is shorter) - xRegisterInt GetNonWide() const - { - return GetOperandSize() == 8 ? xRegisterInt(4, Id) : *this; - } + /// Checks if mapping the ID directly would be a good idea + bool canMapIDTo(int otherSize) const + { + if ((otherSize == 1) == (GetOperandSize() == 1)) + return true; + return isIDSameInAllSizes(); + } - xRegisterInt MatchSizeTo(xRegisterInt other) const; + /// Get a non-wide version of the register (for use with e.g. mov, where `mov eax, 3` and `mov rax, 3` are functionally identical but `mov eax, 3` is shorter) + xRegisterInt GetNonWide() const + { + return GetOperandSize() == 8 ? xRegisterInt(4, Id) : *this; + } - bool operator==(const xRegisterInt &src) const { return Id == src.Id && (GetOperandSize() == src.GetOperandSize()); } - bool operator!=(const xRegisterInt &src) const { return !operator==(src); } -}; + xRegisterInt MatchSizeTo(xRegisterInt other) const; -// -------------------------------------------------------------------------------------- -// xRegister8/16/32/64 - Represents a basic 8/16/32/64 bit GPR on the x86 -// -------------------------------------------------------------------------------------- -class xRegister8 : public xRegisterInt -{ - typedef xRegisterInt _parent; + bool operator==(const xRegisterInt& src) const { return Id == src.Id && (GetOperandSize() == src.GetOperandSize()); } + bool operator!=(const xRegisterInt& src) const { return !operator==(src); } + }; -public: - xRegister8() = default; - explicit xRegister8(int regId) - : _parent(1, regId) - { - } - explicit xRegister8(const xRegisterInt& other) - : _parent(1, other.Id) - { - pxAssertDev(other.canMapIDTo(1), "spl, bpl, sil, dil not yet supported"); - } + // -------------------------------------------------------------------------------------- + // xRegister8/16/32/64 - Represents a basic 8/16/32/64 bit GPR on the x86 + // -------------------------------------------------------------------------------------- + class xRegister8 : public xRegisterInt + { + typedef xRegisterInt _parent; - bool operator==(const xRegister8 &src) const { return Id == src.Id; } - bool operator!=(const xRegister8 &src) const { return Id != src.Id; } -}; + public: + xRegister8() = default; + explicit xRegister8(int regId) + : _parent(1, regId) + { + } + explicit xRegister8(const xRegisterInt& other) + : _parent(1, other.Id) + { + pxAssertDev(other.canMapIDTo(1), "spl, bpl, sil, dil not yet supported"); + } -class xRegister16 : public xRegisterInt -{ - typedef xRegisterInt _parent; + bool operator==(const xRegister8& src) const { return Id == src.Id; } + bool operator!=(const xRegister8& src) const { return Id != src.Id; } + }; -public: - xRegister16() = default; - explicit xRegister16(int regId) - : _parent(2, regId) - { - } - explicit xRegister16(const xRegisterInt& other) - : _parent(2, other.Id) - { - pxAssertDev(other.canMapIDTo(2), "Mapping h registers to higher registers can produce unexpected values"); - } + class xRegister16 : public xRegisterInt + { + typedef xRegisterInt _parent; - bool operator==(const xRegister16 &src) const { return this->Id == src.Id; } - bool operator!=(const xRegister16 &src) const { return this->Id != src.Id; } -}; + public: + xRegister16() = default; + explicit xRegister16(int regId) + : _parent(2, regId) + { + } + explicit xRegister16(const xRegisterInt& other) + : _parent(2, other.Id) + { + pxAssertDev(other.canMapIDTo(2), "Mapping h registers to higher registers can produce unexpected values"); + } -class xRegister32 : public xRegisterInt -{ - typedef xRegisterInt _parent; + bool operator==(const xRegister16& src) const { return this->Id == src.Id; } + bool operator!=(const xRegister16& src) const { return this->Id != src.Id; } + }; -public: - xRegister32() = default; - explicit xRegister32(int regId) - : _parent(4, regId) - { - } - explicit xRegister32(const xRegisterInt& other) - : _parent(4, other.Id) - { - pxAssertDev(other.canMapIDTo(4), "Mapping h registers to higher registers can produce unexpected values"); - } + class xRegister32 : public xRegisterInt + { + typedef xRegisterInt _parent; - bool operator==(const xRegister32 &src) const { return this->Id == src.Id; } - bool operator!=(const xRegister32 &src) const { return this->Id != src.Id; } -}; + public: + xRegister32() = default; + explicit xRegister32(int regId) + : _parent(4, regId) + { + } + explicit xRegister32(const xRegisterInt& other) + : _parent(4, other.Id) + { + pxAssertDev(other.canMapIDTo(4), "Mapping h registers to higher registers can produce unexpected values"); + } -class xRegister64 : public xRegisterInt -{ - typedef xRegisterInt _parent; + bool operator==(const xRegister32& src) const { return this->Id == src.Id; } + bool operator!=(const xRegister32& src) const { return this->Id != src.Id; } + }; -public: - xRegister64() = default; - explicit xRegister64(int regId) - : _parent(8, regId) - { - } - explicit xRegister64(const xRegisterInt& other) - : _parent(8, other.Id) - { - pxAssertDev(other.canMapIDTo(8), "Mapping h registers to higher registers can produce unexpected values"); - } + class xRegister64 : public xRegisterInt + { + typedef xRegisterInt _parent; - bool operator==(const xRegister64 &src) const { return this->Id == src.Id; } - bool operator!=(const xRegister64 &src) const { return this->Id != src.Id; } -}; + public: + xRegister64() = default; + explicit xRegister64(int regId) + : _parent(8, regId) + { + } + explicit xRegister64(const xRegisterInt& other) + : _parent(8, other.Id) + { + pxAssertDev(other.canMapIDTo(8), "Mapping h registers to higher registers can produce unexpected values"); + } -// -------------------------------------------------------------------------------------- -// xRegisterSSE - Represents either a 64 bit or 128 bit SIMD register -// -------------------------------------------------------------------------------------- -// This register type is provided to allow legal syntax for instructions that accept -// an XMM register as a parameter, but do not allow for a GPR. + bool operator==(const xRegister64& src) const { return this->Id == src.Id; } + bool operator!=(const xRegister64& src) const { return this->Id != src.Id; } + }; -class xRegisterSSE : public xRegisterBase -{ - typedef xRegisterBase _parent; + // -------------------------------------------------------------------------------------- + // xRegisterSSE - Represents either a 64 bit or 128 bit SIMD register + // -------------------------------------------------------------------------------------- + // This register type is provided to allow legal syntax for instructions that accept + // an XMM register as a parameter, but do not allow for a GPR. -public: - xRegisterSSE() = default; - explicit xRegisterSSE(int regId) - : _parent(16, regId) - { - } + class xRegisterSSE : public xRegisterBase + { + typedef xRegisterBase _parent; - bool operator==(const xRegisterSSE &src) const { return this->Id == src.Id; } - bool operator!=(const xRegisterSSE &src) const { return this->Id != src.Id; } + public: + xRegisterSSE() = default; + explicit xRegisterSSE(int regId) + : _parent(16, regId) + { + } - static const inline xRegisterSSE &GetInstance(uint id); -}; + bool operator==(const xRegisterSSE& src) const { return this->Id == src.Id; } + bool operator!=(const xRegisterSSE& src) const { return this->Id != src.Id; } -class xRegisterCL : public xRegister8 -{ -public: - xRegisterCL() - : xRegister8(1) - { - } -}; + static const inline xRegisterSSE& GetInstance(uint id); + }; -// -------------------------------------------------------------------------------------- -// xAddressReg -// -------------------------------------------------------------------------------------- -// Use 32/64 bit registers as our index registers (for ModSib-style memory address calculations). -// This type is implicitly exchangeable with xRegister32/64. -// -// Only xAddressReg provides operators for constructing xAddressInfo types. These operators -// could have been added to xRegister32/64 directly instead, however I think this design makes -// more sense and allows the programmer a little more type protection if needed. -// + class xRegisterCL : public xRegister8 + { + public: + xRegisterCL() + : xRegister8(1) + { + } + }; + + // -------------------------------------------------------------------------------------- + // xAddressReg + // -------------------------------------------------------------------------------------- + // Use 32/64 bit registers as our index registers (for ModSib-style memory address calculations). + // This type is implicitly exchangeable with xRegister32/64. + // + // Only xAddressReg provides operators for constructing xAddressInfo types. These operators + // could have been added to xRegister32/64 directly instead, however I think this design makes + // more sense and allows the programmer a little more type protection if needed. + // #ifdef __M_X86_64 #define xRegisterLong xRegister64 #else #define xRegisterLong xRegister32 #endif -static const int wordsize = sizeof(sptr); + static const int wordsize = sizeof(sptr); -class xAddressReg : public xRegisterLong -{ -public: - xAddressReg() = default; - explicit xAddressReg(xRegisterInt other) - : xRegisterLong(other) - { - } - explicit xAddressReg(int regId) - : xRegisterLong(regId) - { - } + class xAddressReg : public xRegisterLong + { + public: + xAddressReg() = default; + explicit xAddressReg(xRegisterInt other) + : xRegisterLong(other) + { + } + explicit xAddressReg(int regId) + : xRegisterLong(regId) + { + } - // Returns true if the register is the stack pointer: ESP. - bool IsStackPointer() const { return Id == 4; } + // Returns true if the register is the stack pointer: ESP. + bool IsStackPointer() const { return Id == 4; } - xAddressVoid operator+(const xAddressReg &right) const; - xAddressVoid operator+(sptr right) const; - xAddressVoid operator+(const void *right) const; - xAddressVoid operator-(sptr right) const; - xAddressVoid operator-(const void *right) const; - xAddressVoid operator*(int factor) const; - xAddressVoid operator<<(u32 shift) const; - xAddressReg& operator=(const xAddressReg&) = default; -}; + xAddressVoid operator+(const xAddressReg& right) const; + xAddressVoid operator+(sptr right) const; + xAddressVoid operator+(const void* right) const; + xAddressVoid operator-(sptr right) const; + xAddressVoid operator-(const void* right) const; + xAddressVoid operator*(int factor) const; + xAddressVoid operator<<(u32 shift) const; + xAddressReg& operator=(const xAddressReg&) = default; + }; -// -------------------------------------------------------------------------------------- -// xRegisterEmpty -// -------------------------------------------------------------------------------------- -struct xRegisterEmpty -{ - operator xRegister8() const - { - return xRegister8(xRegId_Empty); - } + // -------------------------------------------------------------------------------------- + // xRegisterEmpty + // -------------------------------------------------------------------------------------- + struct xRegisterEmpty + { + operator xRegister8() const + { + return xRegister8(xRegId_Empty); + } - operator xRegister16() const - { - return xRegister16(xRegId_Empty); - } + operator xRegister16() const + { + return xRegister16(xRegId_Empty); + } - operator xRegister32() const - { - return xRegister32(xRegId_Empty); - } + operator xRegister32() const + { + return xRegister32(xRegId_Empty); + } - operator xRegisterSSE() const - { - return xRegisterSSE(xRegId_Empty); - } + operator xRegisterSSE() const + { + return xRegisterSSE(xRegId_Empty); + } - operator xAddressReg() const - { - return xAddressReg(xRegId_Empty); - } -}; + operator xAddressReg() const + { + return xAddressReg(xRegId_Empty); + } + }; -class xRegister16or32or64 -{ -protected: - const xRegisterInt &m_convtype; + class xRegister16or32or64 + { + protected: + const xRegisterInt& m_convtype; -public: - xRegister16or32or64(const xRegister64 &src) - : m_convtype(src) - { - } - xRegister16or32or64(const xRegister32 &src) - : m_convtype(src) - { - } - xRegister16or32or64(const xRegister16 &src) - : m_convtype(src) - { - } + public: + xRegister16or32or64(const xRegister64& src) + : m_convtype(src) + { + } + xRegister16or32or64(const xRegister32& src) + : m_convtype(src) + { + } + xRegister16or32or64(const xRegister16& src) + : m_convtype(src) + { + } - operator const xRegisterBase &() const { return m_convtype; } + operator const xRegisterBase&() const { return m_convtype; } - const xRegisterInt *operator->() const - { - return &m_convtype; - } -}; + const xRegisterInt* operator->() const + { + return &m_convtype; + } + }; -class xRegister32or64 -{ -protected: - const xRegisterInt &m_convtype; + class xRegister32or64 + { + protected: + const xRegisterInt& m_convtype; -public: - xRegister32or64(const xRegister64 &src) - : m_convtype(src) - { - } - xRegister32or64(const xRegister32 &src) - : m_convtype(src) - { - } + public: + xRegister32or64(const xRegister64& src) + : m_convtype(src) + { + } + xRegister32or64(const xRegister32& src) + : m_convtype(src) + { + } - operator const xRegisterBase &() const { return m_convtype; } + operator const xRegisterBase&() const { return m_convtype; } - const xRegisterInt *operator->() const - { - return &m_convtype; - } -}; + const xRegisterInt* operator->() const + { + return &m_convtype; + } + }; -extern const xRegisterEmpty xEmptyReg; + extern const xRegisterEmpty xEmptyReg; -// clang-format off + // clang-format off extern const xRegisterSSE xmm0, xmm1, xmm2, xmm3, @@ -638,330 +655,330 @@ extern const xRegister32 calleeSavedReg2d; -// clang-format on + // clang-format on -extern const xRegisterCL cl; // I'm special! + extern const xRegisterCL cl; // I'm special! -const xRegisterSSE &xRegisterSSE::GetInstance(uint id) -{ - static const xRegisterSSE *const m_tbl_xmmRegs[] = - { - &xmm0, &xmm1, &xmm2, &xmm3, - &xmm4, &xmm5, &xmm6, &xmm7, - &xmm8, &xmm9, &xmm10, &xmm11, - &xmm12, &xmm13, &xmm14, &xmm15}; + const xRegisterSSE& xRegisterSSE::GetInstance(uint id) + { + static const xRegisterSSE* const m_tbl_xmmRegs[] = + { + &xmm0, &xmm1, &xmm2, &xmm3, + &xmm4, &xmm5, &xmm6, &xmm7, + &xmm8, &xmm9, &xmm10, &xmm11, + &xmm12, &xmm13, &xmm14, &xmm15}; - pxAssert(id < iREGCNT_XMM); - return *m_tbl_xmmRegs[id]; -} + pxAssert(id < iREGCNT_XMM); + return *m_tbl_xmmRegs[id]; + } -// -------------------------------------------------------------------------------------- -// xAddressVoid -// -------------------------------------------------------------------------------------- -class xAddressVoid -{ -public: - xAddressReg Base; // base register (no scale) - xAddressReg Index; // index reg gets multiplied by the scale - int Factor; // scale applied to the index register, in factor form (not a shift!) - sptr Displacement; // address displacement // 4B max even on 64 bits but keep rest for assertions + // -------------------------------------------------------------------------------------- + // xAddressVoid + // -------------------------------------------------------------------------------------- + class xAddressVoid + { + public: + xAddressReg Base; // base register (no scale) + xAddressReg Index; // index reg gets multiplied by the scale + int Factor; // scale applied to the index register, in factor form (not a shift!) + sptr Displacement; // address displacement // 4B max even on 64 bits but keep rest for assertions -public: - xAddressVoid(const xAddressReg &base, const xAddressReg &index, int factor = 1, sptr displacement = 0); + public: + xAddressVoid(const xAddressReg& base, const xAddressReg& index, int factor = 1, sptr displacement = 0); - xAddressVoid(const xAddressReg &index, sptr displacement = 0); - explicit xAddressVoid(const void *displacement); - explicit xAddressVoid(sptr displacement = 0); + xAddressVoid(const xAddressReg& index, sptr displacement = 0); + explicit xAddressVoid(const void* displacement); + explicit xAddressVoid(sptr displacement = 0); -public: - bool IsByteSizeDisp() const { return is_s8(Displacement); } + public: + bool IsByteSizeDisp() const { return is_s8(Displacement); } - xAddressVoid &Add(sptr imm) - { - Displacement += imm; - return *this; - } + xAddressVoid& Add(sptr imm) + { + Displacement += imm; + return *this; + } - xAddressVoid &Add(const xAddressReg &src); - xAddressVoid &Add(const xAddressVoid &src); + xAddressVoid& Add(const xAddressReg& src); + xAddressVoid& Add(const xAddressVoid& src); - __fi xAddressVoid operator+(const xAddressReg &right) const { return xAddressVoid(*this).Add(right); } - __fi xAddressVoid operator+(const xAddressVoid &right) const { return xAddressVoid(*this).Add(right); } - __fi xAddressVoid operator+(sptr imm) const { return xAddressVoid(*this).Add(imm); } - __fi xAddressVoid operator-(sptr imm) const { return xAddressVoid(*this).Add(-imm); } - __fi xAddressVoid operator+(const void *addr) const { return xAddressVoid(*this).Add((uptr)addr); } + __fi xAddressVoid operator+(const xAddressReg& right) const { return xAddressVoid(*this).Add(right); } + __fi xAddressVoid operator+(const xAddressVoid& right) const { return xAddressVoid(*this).Add(right); } + __fi xAddressVoid operator+(sptr imm) const { return xAddressVoid(*this).Add(imm); } + __fi xAddressVoid operator-(sptr imm) const { return xAddressVoid(*this).Add(-imm); } + __fi xAddressVoid operator+(const void* addr) const { return xAddressVoid(*this).Add((uptr)addr); } - __fi void operator+=(const xAddressReg &right) { Add(right); } - __fi void operator+=(sptr imm) { Add(imm); } - __fi void operator-=(sptr imm) { Add(-imm); } -}; + __fi void operator+=(const xAddressReg& right) { Add(right); } + __fi void operator+=(sptr imm) { Add(imm); } + __fi void operator-=(sptr imm) { Add(-imm); } + }; -static __fi xAddressVoid operator+(const void *addr, const xAddressVoid &right) -{ - return right + addr; -} + static __fi xAddressVoid operator+(const void* addr, const xAddressVoid& right) + { + return right + addr; + } -static __fi xAddressVoid operator+(sptr addr, const xAddressVoid &right) -{ - return right + addr; -} + static __fi xAddressVoid operator+(sptr addr, const xAddressVoid& right) + { + return right + addr; + } -// -------------------------------------------------------------------------------------- -// xImmReg< typename xRegType > -// -------------------------------------------------------------------------------------- -// Used to represent an immediate value which can also be optimized to a register. Note -// that the immediate value represented by this structure is *always* legal. The register -// assignment is an optional optimization which can be implemented in cases where an -// immediate is used enough times to merit allocating it to a register. -// -// Note: not all instructions support this operand type (yet). You can always implement it -// manually by checking the status of IsReg() and generating the xOP conditionally. -// -template -class xImmReg -{ - xRegType m_reg; - int m_imm; + // -------------------------------------------------------------------------------------- + // xImmReg< typename xRegType > + // -------------------------------------------------------------------------------------- + // Used to represent an immediate value which can also be optimized to a register. Note + // that the immediate value represented by this structure is *always* legal. The register + // assignment is an optional optimization which can be implemented in cases where an + // immediate is used enough times to merit allocating it to a register. + // + // Note: not all instructions support this operand type (yet). You can always implement it + // manually by checking the status of IsReg() and generating the xOP conditionally. + // + template + class xImmReg + { + xRegType m_reg; + int m_imm; -public: - xImmReg() - : m_reg() - { - m_imm = 0; - } + public: + xImmReg() + : m_reg() + { + m_imm = 0; + } - xImmReg(int imm, const xRegType ® = xEmptyReg) - { - m_reg = reg; - m_imm = imm; - } + xImmReg(int imm, const xRegType& reg = xEmptyReg) + { + m_reg = reg; + m_imm = imm; + } - const xRegType &GetReg() const { return m_reg; } - int GetImm() const { return m_imm; } - bool IsReg() const { return !m_reg.IsEmpty(); } -}; + const xRegType& GetReg() const { return m_reg; } + int GetImm() const { return m_imm; } + bool IsReg() const { return !m_reg.IsEmpty(); } + }; -// -------------------------------------------------------------------------------------- -// xIndirectVoid - Internal low-level representation of the ModRM/SIB information. -// -------------------------------------------------------------------------------------- -// This class serves two purposes: It houses 'reduced' ModRM/SIB info only, which means -// that the Base, Index, Scale, and Displacement values are all in the correct arrange- -// ments, and it serves as a type-safe layer between the xRegister's operators (which -// generate xAddressInfo types) and the emitter's ModSib instruction forms. Without this, -// the xRegister would pass as a ModSib type implicitly, and that would cause ambiguity -// on a number of instructions. -// -// End users should always use xAddressInfo instead. -// -class xIndirectVoid : public OperandSizedObject -{ -public: - xAddressReg Base; // base register (no scale) - xAddressReg Index; // index reg gets multiplied by the scale - uint Scale; // scale applied to the index register, in scale/shift form - sptr Displacement; // offset applied to the Base/Index registers. - // Displacement is 8/32 bits even on x86_64 - // However we need the whole pointer to calculate rip-relative offsets + // -------------------------------------------------------------------------------------- + // xIndirectVoid - Internal low-level representation of the ModRM/SIB information. + // -------------------------------------------------------------------------------------- + // This class serves two purposes: It houses 'reduced' ModRM/SIB info only, which means + // that the Base, Index, Scale, and Displacement values are all in the correct arrange- + // ments, and it serves as a type-safe layer between the xRegister's operators (which + // generate xAddressInfo types) and the emitter's ModSib instruction forms. Without this, + // the xRegister would pass as a ModSib type implicitly, and that would cause ambiguity + // on a number of instructions. + // + // End users should always use xAddressInfo instead. + // + class xIndirectVoid : public OperandSizedObject + { + public: + xAddressReg Base; // base register (no scale) + xAddressReg Index; // index reg gets multiplied by the scale + uint Scale; // scale applied to the index register, in scale/shift form + sptr Displacement; // offset applied to the Base/Index registers. + // Displacement is 8/32 bits even on x86_64 + // However we need the whole pointer to calculate rip-relative offsets -public: - explicit xIndirectVoid(sptr disp); - explicit xIndirectVoid(const xAddressVoid &src); - xIndirectVoid(xAddressReg base, xAddressReg index, int scale = 0, sptr displacement = 0); - xIndirectVoid &Add(sptr imm); + public: + explicit xIndirectVoid(sptr disp); + explicit xIndirectVoid(const xAddressVoid& src); + xIndirectVoid(xAddressReg base, xAddressReg index, int scale = 0, sptr displacement = 0); + xIndirectVoid& Add(sptr imm); - bool IsByteSizeDisp() const { return is_s8(Displacement); } - bool IsMem() const { return true; } - bool IsReg() const { return false; } - bool IsExtended() const { return false; } // Non sense but ease template - bool IsWide() const { return GetOperandSize() == 8; } + bool IsByteSizeDisp() const { return is_s8(Displacement); } + bool IsMem() const { return true; } + bool IsReg() const { return false; } + bool IsExtended() const { return false; } // Non sense but ease template + bool IsWide() const { return GetOperandSize() == 8; } - operator xAddressVoid() - { - return xAddressVoid(Base, Index, Scale, Displacement); - } + operator xAddressVoid() + { + return xAddressVoid(Base, Index, Scale, Displacement); + } - __fi xIndirectVoid operator+(const sptr imm) const { return xIndirectVoid(*this).Add(imm); } - __fi xIndirectVoid operator-(const sptr imm) const { return xIndirectVoid(*this).Add(-imm); } + __fi xIndirectVoid operator+(const sptr imm) const { return xIndirectVoid(*this).Add(imm); } + __fi xIndirectVoid operator-(const sptr imm) const { return xIndirectVoid(*this).Add(-imm); } -protected: - void Reduce(); -}; + protected: + void Reduce(); + }; -template -class xIndirect : public xIndirectVoid -{ - typedef xIndirectVoid _parent; + template + class xIndirect : public xIndirectVoid + { + typedef xIndirectVoid _parent; -public: - explicit xIndirect(sptr disp) - : _parent(disp) - { - _operandSize = sizeof(OperandType); - } - xIndirect(xAddressReg base, xAddressReg index, int scale = 0, sptr displacement = 0) - : _parent(base, index, scale, displacement) - { - _operandSize = sizeof(OperandType); - } - explicit xIndirect(const xIndirectVoid& other) - : _parent(other) - { - } + public: + explicit xIndirect(sptr disp) + : _parent(disp) + { + _operandSize = sizeof(OperandType); + } + xIndirect(xAddressReg base, xAddressReg index, int scale = 0, sptr displacement = 0) + : _parent(base, index, scale, displacement) + { + _operandSize = sizeof(OperandType); + } + explicit xIndirect(const xIndirectVoid& other) + : _parent(other) + { + } - xIndirect &Add(sptr imm) - { - Displacement += imm; - return *this; - } + xIndirect& Add(sptr imm) + { + Displacement += imm; + return *this; + } - __fi xIndirect operator+(const sptr imm) const { return xIndirect(*this).Add(imm); } - __fi xIndirect operator-(const sptr imm) const { return xIndirect(*this).Add(-imm); } + __fi xIndirect operator+(const sptr imm) const { return xIndirect(*this).Add(imm); } + __fi xIndirect operator-(const sptr imm) const { return xIndirect(*this).Add(-imm); } - bool operator==(const xIndirect &src) const - { - return (Base == src.Base) && (Index == src.Index) && - (Scale == src.Scale) && (Displacement == src.Displacement); - } + bool operator==(const xIndirect& src) const + { + return (Base == src.Base) && (Index == src.Index) && + (Scale == src.Scale) && (Displacement == src.Displacement); + } - bool operator!=(const xIndirect &src) const - { - return !operator==(src); - } + bool operator!=(const xIndirect& src) const + { + return !operator==(src); + } -protected: - void Reduce(); -}; + protected: + void Reduce(); + }; -typedef xIndirect xIndirect128; -typedef xIndirect xIndirect64; -typedef xIndirect xIndirect32; -typedef xIndirect xIndirect16; -typedef xIndirect xIndirect8; + typedef xIndirect xIndirect128; + typedef xIndirect xIndirect64; + typedef xIndirect xIndirect32; + typedef xIndirect xIndirect16; + typedef xIndirect xIndirect8; #ifdef __M_X86_64 -typedef xIndirect xIndirectNative; + typedef xIndirect xIndirectNative; #else -typedef xIndirect xIndirectNative; + typedef xIndirect xIndirectNative; #endif -// -------------------------------------------------------------------------------------- -// xIndirect64orLess - base class 64, 32, 16, and 8 bit operand types -// -------------------------------------------------------------------------------------- -class xIndirect64orLess : public xIndirectVoid -{ - typedef xIndirectVoid _parent; + // -------------------------------------------------------------------------------------- + // xIndirect64orLess - base class 64, 32, 16, and 8 bit operand types + // -------------------------------------------------------------------------------------- + class xIndirect64orLess : public xIndirectVoid + { + typedef xIndirectVoid _parent; -public: - xIndirect64orLess(const xIndirect8 &src) - : _parent(src) - { - } - xIndirect64orLess(const xIndirect16 &src) - : _parent(src) - { - } - xIndirect64orLess(const xIndirect32 &src) - : _parent(src) - { - } - xIndirect64orLess(const xIndirect64 &src) - : _parent(src) - { - } -}; + public: + xIndirect64orLess(const xIndirect8& src) + : _parent(src) + { + } + xIndirect64orLess(const xIndirect16& src) + : _parent(src) + { + } + xIndirect64orLess(const xIndirect32& src) + : _parent(src) + { + } + xIndirect64orLess(const xIndirect64& src) + : _parent(src) + { + } + }; -// -------------------------------------------------------------------------------------- -// xAddressIndexer -// -------------------------------------------------------------------------------------- -// This is a type-translation "interface class" which provisions our ptr[] syntax. -// xAddressReg types go in, and xIndirectVoid derived types come out. -// -template -class xAddressIndexer -{ -public: - // passthrough instruction, allows ModSib to pass silently through ptr translation - // without doing anything and without compiler error. - const xModSibType &operator[](const xModSibType &src) const { return src; } + // -------------------------------------------------------------------------------------- + // xAddressIndexer + // -------------------------------------------------------------------------------------- + // This is a type-translation "interface class" which provisions our ptr[] syntax. + // xAddressReg types go in, and xIndirectVoid derived types come out. + // + template + class xAddressIndexer + { + public: + // passthrough instruction, allows ModSib to pass silently through ptr translation + // without doing anything and without compiler error. + const xModSibType& operator[](const xModSibType& src) const { return src; } - xModSibType operator[](const xAddressReg &src) const - { - return xModSibType(src, xEmptyReg); - } + xModSibType operator[](const xAddressReg& src) const + { + return xModSibType(src, xEmptyReg); + } - xModSibType operator[](const xAddressVoid &src) const - { - return xModSibType(src.Base, src.Index, src.Factor, src.Displacement); - } + xModSibType operator[](const xAddressVoid& src) const + { + return xModSibType(src.Base, src.Index, src.Factor, src.Displacement); + } - xModSibType operator[](const void *src) const - { - return xModSibType((uptr)src); - } -}; + xModSibType operator[](const void* src) const + { + return xModSibType((uptr)src); + } + }; -// ptr[] - use this form for instructions which can resolve the address operand size from -// the other register operand sizes. -extern const xAddressIndexer ptr; -extern const xAddressIndexer ptrNative; -extern const xAddressIndexer ptr128; -extern const xAddressIndexer ptr64; -extern const xAddressIndexer ptr32; -extern const xAddressIndexer ptr16; -extern const xAddressIndexer ptr8; + // ptr[] - use this form for instructions which can resolve the address operand size from + // the other register operand sizes. + extern const xAddressIndexer ptr; + extern const xAddressIndexer ptrNative; + extern const xAddressIndexer ptr128; + extern const xAddressIndexer ptr64; + extern const xAddressIndexer ptr32; + extern const xAddressIndexer ptr16; + extern const xAddressIndexer ptr8; -// -------------------------------------------------------------------------------------- -// xForwardJump -// -------------------------------------------------------------------------------------- -// Primary use of this class is through the various xForwardJA8/xForwardJLE32/etc. helpers -// defined later in this header. :) -// + // -------------------------------------------------------------------------------------- + // xForwardJump + // -------------------------------------------------------------------------------------- + // Primary use of this class is through the various xForwardJA8/xForwardJLE32/etc. helpers + // defined later in this header. :) + // -class xForwardJumpBase -{ -public: - // pointer to base of the instruction *Following* the jump. The jump address will be - // relative to this address. - s8 *BasePtr; + class xForwardJumpBase + { + public: + // pointer to base of the instruction *Following* the jump. The jump address will be + // relative to this address. + s8* BasePtr; -public: - xForwardJumpBase(uint opsize, JccComparisonType cctype); + public: + xForwardJumpBase(uint opsize, JccComparisonType cctype); -protected: - void _setTarget(uint opsize) const; -}; + protected: + void _setTarget(uint opsize) const; + }; -template -class xForwardJump : public xForwardJumpBase -{ -public: - static const uint OperandSize = sizeof(OperandType); + template + class xForwardJump : public xForwardJumpBase + { + public: + static const uint OperandSize = sizeof(OperandType); - // The jump instruction is emitted at the point of object construction. The conditional - // type must be valid (Jcc_Unknown generates an assertion). - xForwardJump(JccComparisonType cctype = Jcc_Unconditional) - : xForwardJumpBase(OperandSize, cctype) - { - } + // The jump instruction is emitted at the point of object construction. The conditional + // type must be valid (Jcc_Unknown generates an assertion). + xForwardJump(JccComparisonType cctype = Jcc_Unconditional) + : xForwardJumpBase(OperandSize, cctype) + { + } - // Sets the jump target by writing back the current x86Ptr to the jump instruction. - // This method can be called multiple times, re-writing the jump instruction's target - // in each case. (the the last call is the one that takes effect). - void SetTarget() const - { - _setTarget(OperandSize); - } -}; + // Sets the jump target by writing back the current x86Ptr to the jump instruction. + // This method can be called multiple times, re-writing the jump instruction's target + // in each case. (the the last call is the one that takes effect). + void SetTarget() const + { + _setTarget(OperandSize); + } + }; -static __fi xAddressVoid operator+(const void *addr, const xAddressReg ®) -{ - return reg + (sptr)addr; -} + static __fi xAddressVoid operator+(const void* addr, const xAddressReg& reg) + { + return reg + (sptr)addr; + } -static __fi xAddressVoid operator+(sptr addr, const xAddressReg ®) -{ - return reg + (sptr)addr; -} -} + static __fi xAddressVoid operator+(sptr addr, const xAddressReg& reg) + { + return reg + (sptr)addr; + } +} // namespace x86Emitter #include "implement/helpers.h" @@ -974,7 +991,7 @@ static __fi xAddressVoid operator+(sptr addr, const xAddressReg ®) #include "implement/group1.h" #include "implement/group2.h" #include "implement/group3.h" -#include "implement/movs.h" // cmov and movsx/zx +#include "implement/movs.h" // cmov and movsx/zx #include "implement/dwshift.h" // doubleword shifts! #include "implement/incdec.h" #include "implement/test.h" diff --git a/common/pxCheckBox.cpp b/common/pxCheckBox.cpp index f15e8c669c..c7ee06cbe5 100644 --- a/common/pxCheckBox.cpp +++ b/common/pxCheckBox.cpp @@ -22,115 +22,117 @@ using namespace pxSizerFlags; // pxCheckBox Implementations // -------------------------------------------------------------------------------------- -pxCheckBox::pxCheckBox(wxWindow *parent, const wxString &label, const wxString &subtext, int flags) - : wxPanelWithHelpers(parent, wxVERTICAL) +pxCheckBox::pxCheckBox(wxWindow* parent, const wxString& label, const wxString& subtext, int flags) + : wxPanelWithHelpers(parent, wxVERTICAL) { - Init(label, subtext, flags); + Init(label, subtext, flags); } -pxCheckBox::pxCheckBox(wxWindow *parent, const wxString &label, int flags) - : wxPanelWithHelpers(parent, wxVERTICAL) +pxCheckBox::pxCheckBox(wxWindow* parent, const wxString& label, int flags) + : wxPanelWithHelpers(parent, wxVERTICAL) { - Init(label, wxEmptyString, flags); + Init(label, wxEmptyString, flags); } -void pxCheckBox::Init(const wxString &label, const wxString &subtext, int flags) +void pxCheckBox::Init(const wxString& label, const wxString& subtext, int flags) { - m_subtext = NULL; - m_subPadding = StdPadding * 2; - m_checkbox = new wxCheckBox(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, flags); + m_subtext = NULL; + m_subPadding = StdPadding * 2; + m_checkbox = new wxCheckBox(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, flags); - *this += m_checkbox | pxSizerFlags::StdExpand(); + *this += m_checkbox | pxSizerFlags::StdExpand(); - static const int Indentation = 23; - if (!subtext.IsEmpty()) { - m_subtext = new pxStaticText(this, subtext, wxALIGN_LEFT); + static const int Indentation = 23; + if (!subtext.IsEmpty()) + { + m_subtext = new pxStaticText(this, subtext, wxALIGN_LEFT); - wxFlexGridSizer &spaced(*new wxFlexGridSizer(3)); - spaced.AddGrowableCol(1); - spaced += Indentation; - m_sizerItem_subtext = spaced.Add(m_subtext, pxBorder(wxBOTTOM, m_subPadding).Expand()); - //spaced += pxSizerFlags::StdPadding; + wxFlexGridSizer& spaced(*new wxFlexGridSizer(3)); + spaced.AddGrowableCol(1); + spaced += Indentation; + m_sizerItem_subtext = spaced.Add(m_subtext, pxBorder(wxBOTTOM, m_subPadding).Expand()); + //spaced += pxSizerFlags::StdPadding; - *this += &spaced | pxExpand; - } + *this += &spaced | pxExpand; + } - Bind(wxEVT_CHECKBOX, &pxCheckBox::OnCheckpartCommand, this, m_checkbox->GetId()); + Bind(wxEVT_CHECKBOX, &pxCheckBox::OnCheckpartCommand, this, m_checkbox->GetId()); } -pxCheckBox &pxCheckBox::SetSubPadding(int pad) +pxCheckBox& pxCheckBox::SetSubPadding(int pad) { - m_subPadding = pad; - if (m_sizerItem_subtext) { - m_sizerItem_subtext->SetBorder(m_subPadding); - Fit(); - } - return *this; + m_subPadding = pad; + if (m_sizerItem_subtext) + { + m_sizerItem_subtext->SetBorder(m_subPadding); + Fit(); + } + return *this; } // applies the tooltip to both both the checkbox and it's static subtext (if present), and // performs word wrapping on platforms that need it (eg mswindows). -pxCheckBox &pxCheckBox::SetToolTip(const wxString &tip) +pxCheckBox& pxCheckBox::SetToolTip(const wxString& tip) { - pxSetToolTip(m_checkbox, tip); - pxSetToolTip(m_subtext, tip); - return *this; + pxSetToolTip(m_checkbox, tip); + pxSetToolTip(m_subtext, tip); + return *this; } -pxCheckBox &pxCheckBox::SetValue(bool val) +pxCheckBox& pxCheckBox::SetValue(bool val) { - pxAssert(m_checkbox); - m_checkbox->SetValue(val); - return *this; + pxAssert(m_checkbox); + m_checkbox->SetValue(val); + return *this; } -pxCheckBox &pxCheckBox::SetIndeterminate() +pxCheckBox& pxCheckBox::SetIndeterminate() { - pxAssert(m_checkbox); - m_checkbox->Set3StateValue(wxCHK_UNDETERMINED); - return *this; + pxAssert(m_checkbox); + m_checkbox->Set3StateValue(wxCHK_UNDETERMINED); + return *this; } -pxCheckBox &pxCheckBox::SetState(wxCheckBoxState state) +pxCheckBox& pxCheckBox::SetState(wxCheckBoxState state) { - pxAssert(m_checkbox); - m_checkbox->Set3StateValue(state); - return *this; + pxAssert(m_checkbox); + m_checkbox->Set3StateValue(state); + return *this; } // Forwards checkbox actions on the internal checkbox (called 'checkpart') to listeners // bound to the pxCheckBox "parent" panel. This helps the pxCheckBox behave more like a // traditional checkbox. -void pxCheckBox::OnCheckpartCommand(wxCommandEvent &evt) +void pxCheckBox::OnCheckpartCommand(wxCommandEvent& evt) { - evt.Skip(); + evt.Skip(); - wxCommandEvent newevt(evt); - newevt.SetEventObject(this); - newevt.SetId(GetId()); - GetEventHandler()->ProcessEvent(newevt); + wxCommandEvent newevt(evt); + newevt.SetEventObject(this); + newevt.SetId(GetId()); + GetEventHandler()->ProcessEvent(newevt); } -void pxCheckBox::OnSubtextClicked(wxCommandEvent &evt) +void pxCheckBox::OnSubtextClicked(wxCommandEvent& evt) { - // TODO? - // We can enable the ability to allow clicks on the subtext desc/label to toggle - // the checkmark. Not sure if that's desirable. + // TODO? + // We can enable the ability to allow clicks on the subtext desc/label to toggle + // the checkmark. Not sure if that's desirable. } -void operator+=(wxSizer &target, pxCheckBox *src) +void operator+=(wxSizer& target, pxCheckBox* src) { - if (src) - target.Add(src, pxExpand); + if (src) + target.Add(src, pxExpand); } -void operator+=(wxSizer &target, pxCheckBox &src) +void operator+=(wxSizer& target, pxCheckBox& src) { - target.Add(&src, pxExpand); + target.Add(&src, pxExpand); } -void operator+=(wxSizer *target, pxCheckBox &src) +void operator+=(wxSizer* target, pxCheckBox& src) { - target->Add(&src, pxExpand); + target->Add(&src, pxExpand); } diff --git a/common/pxCheckBox.h b/common/pxCheckBox.h index 60154b5063..667336b314 100644 --- a/common/pxCheckBox.h +++ b/common/pxCheckBox.h @@ -29,74 +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() = default; + pxCheckBox(wxWindow* parent, const wxString& label, const wxString& subtext = wxEmptyString, int flags = wxCHK_2STATE); + pxCheckBox(wxWindow* parent, const wxString& label, int flags); + virtual ~pxCheckBox() = default; - 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 &src) +inline void operator+=(wxSizer& target, const pxWindowAndFlags& src) { - target.Add(src.window, src.flags); + target.Add(src.window, src.flags); } diff --git a/common/pxEvents.h b/common/pxEvents.h index 805769b775..e3b2b3e69e 100644 --- a/common/pxEvents.h +++ b/common/pxEvents.h @@ -31,36 +31,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() = default; + virtual ~SynchronousActionState() = default; - 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(); }; @@ -73,21 +73,21 @@ public: // class pxSimpleEvent : public wxEvent { - wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSimpleEvent); + wxDECLARE_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) + { + } - pxSimpleEvent(const pxSimpleEvent&) = default; - virtual wxEvent *Clone() const { return new pxSimpleEvent(*this); } + pxSimpleEvent(const pxSimpleEvent&) = default; + virtual wxEvent* Clone() const { return new pxSimpleEvent(*this); } }; // -------------------------------------------------------------------------------------- @@ -99,41 +99,41 @@ wxDECLARE_EVENT(pxEvt_InvokeAction, pxActionEvent); class pxActionEvent : public wxEvent { - wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxActionEvent); + wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxActionEvent); protected: - SynchronousActionState *m_state; + SynchronousActionState* m_state; public: - virtual ~pxActionEvent() = default; - virtual pxActionEvent *Clone() const { return new pxActionEvent(*this); } + virtual ~pxActionEvent() = default; + 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 perform whatever action it is - // the event is supposed to do. :) Thread affinity is guaranteed 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 perform whatever action it is + // the event is supposed to do. :) Thread affinity is guaranteed 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() {} }; @@ -142,27 +142,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() - { - } + virtual ~pxExceptionEvent() + { + } - virtual pxExceptionEvent *Clone() const { return new pxExceptionEvent(*this); } + virtual pxExceptionEvent* Clone() const { return new pxExceptionEvent(*this); } protected: - void InvokeEvent(); + void InvokeEvent(); }; // -------------------------------------------------------------------------------------- @@ -171,29 +171,29 @@ protected: class pxSynchronousCommandEvent : public wxCommandEvent { - wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSynchronousCommandEvent); + wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSynchronousCommandEvent); protected: - SynchronousActionState *m_sync; - wxEventType m_realEvent; + SynchronousActionState* m_sync; + wxEventType m_realEvent; public: - virtual ~pxSynchronousCommandEvent() = default; - virtual pxSynchronousCommandEvent *Clone() const { return new pxSynchronousCommandEvent(*this); } + virtual ~pxSynchronousCommandEvent() = default; + 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); @@ -203,23 +203,23 @@ wxDECLARE_EVENT(pxEvt_SynchronousCommand, pxSynchronousCommandEvent); // -------------------------------------------------------------------------------------- class BaseMessageBoxEvent : public pxActionEvent { - typedef pxActionEvent _parent; - wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(BaseMessageBoxEvent); + typedef pxActionEvent _parent; + wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(BaseMessageBoxEvent); protected: - wxString m_Content; + wxString m_Content; public: - virtual ~BaseMessageBoxEvent() = default; - virtual BaseMessageBoxEvent *Clone() const { return new BaseMessageBoxEvent(*this); } + virtual ~BaseMessageBoxEvent() = default; + 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; }; // -------------------------------------------------------------------------------------- @@ -228,134 +228,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); + } }; // -------------------------------------------------------------------------------------- @@ -378,24 +378,24 @@ public: // class pxMessageBoxEvent : public BaseMessageBoxEvent { - typedef BaseMessageBoxEvent _parent; - wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxMessageBoxEvent); + typedef BaseMessageBoxEvent _parent; + wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxMessageBoxEvent); protected: - wxString m_Title; - MsgButtons m_Buttons; + wxString m_Title; + MsgButtons m_Buttons; public: - virtual ~pxMessageBoxEvent() = default; - virtual pxMessageBoxEvent *Clone() const { return new pxMessageBoxEvent(*this); } + virtual ~pxMessageBoxEvent() = default; + 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) = default; + 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) = default; protected: - int _DoDialog() const; + int _DoDialog() const; }; // -------------------------------------------------------------------------------------- @@ -403,22 +403,22 @@ protected: // -------------------------------------------------------------------------------------- class pxAssertionEvent : public BaseMessageBoxEvent { - typedef BaseMessageBoxEvent _parent; - wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxAssertionEvent); + typedef BaseMessageBoxEvent _parent; + wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxAssertionEvent); protected: - wxString m_Stacktrace; + wxString m_Stacktrace; public: - virtual ~pxAssertionEvent() = default; - virtual pxAssertionEvent *Clone() const { return new pxAssertionEvent(*this); } + virtual ~pxAssertionEvent() = default; + 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) = default; + 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) = default; - pxAssertionEvent &SetStacktrace(const wxString &trace); + pxAssertionEvent& SetStacktrace(const wxString& trace); protected: - int _DoDialog() const; + int _DoDialog() const; }; diff --git a/common/pxForwardDefs.h b/common/pxForwardDefs.h index b1c283f642..be585ccfa9 100644 --- a/common/pxForwardDefs.h +++ b/common/pxForwardDefs.h @@ -40,12 +40,12 @@ extern const wxPoint wxDefaultPosition; namespace Threading { -class Mutex; -class Semaphore; -class pxThread; -} + class Mutex; + class Semaphore; + class pxThread; +} // namespace Threading namespace Exception { -class BaseException; + class BaseException; } diff --git a/common/pxRadioPanel.cpp b/common/pxRadioPanel.cpp index e5d60c5f1d..4421667bdd 100644 --- a/common/pxRadioPanel.cpp +++ b/common/pxRadioPanel.cpp @@ -24,232 +24,239 @@ template class SafeArray; // =========================================================================================== #define VerifyRealizedState() \ - pxAssertDev(m_IsRealized, "Invalid object state: RadioButtonGroup as not been realized.") + pxAssertDev(m_IsRealized, "Invalid object state: RadioButtonGroup as not been realized.") -void pxRadioPanel::Init(const RadioPanelItem *srcArray, int arrsize) +void pxRadioPanel::Init(const RadioPanelItem* srcArray, int arrsize) { - m_DefaultIdx = -1; - m_IsRealized = false; + m_DefaultIdx = -1; + m_IsRealized = false; - // FIXME: This probably needs to be platform-dependent, and/or based on font size. - m_Indentation = 23; + // FIXME: This probably needs to be platform-dependent, and/or based on font size. + m_Indentation = 23; - for (int i = 0; i < arrsize; ++i) - Append(srcArray[i]); + for (int i = 0; i < arrsize; ++i) + Append(srcArray[i]); } -pxRadioPanel &pxRadioPanel::Append(const RadioPanelItem &entry) +pxRadioPanel& pxRadioPanel::Append(const RadioPanelItem& entry) { - m_buttonStrings.push_back(entry); - return *this; + m_buttonStrings.push_back(entry); + return *this; } void pxRadioPanel::Reset() { - m_IsRealized = false; - const int numbuttons = m_buttonStrings.size(); - if (numbuttons == 0) - return; + m_IsRealized = false; + const int numbuttons = m_buttonStrings.size(); + if (numbuttons == 0) + return; - for (int i = 0; i < numbuttons; ++i) { - safe_delete(m_objects[i].LabelObj); - safe_delete(m_objects[i].SubTextObj); - } - m_buttonStrings.clear(); + for (int i = 0; i < numbuttons; ++i) + { + safe_delete(m_objects[i].LabelObj); + safe_delete(m_objects[i].SubTextObj); + } + m_buttonStrings.clear(); } void pxRadioPanel::Realize() { - const int numbuttons = m_buttonStrings.size(); - if (numbuttons == 0) - return; - if (m_IsRealized) - return; - m_IsRealized = true; + const int numbuttons = m_buttonStrings.size(); + if (numbuttons == 0) + return; + if (m_IsRealized) + return; + m_IsRealized = true; - m_objects.MakeRoomFor(numbuttons); + m_objects.MakeRoomFor(numbuttons); - // Add all RadioButtons in one pass, and then go back and create all the subtext - // objects. This ensures the radio buttons have consecutive tab order IDs, which - // is the "preferred" method when using grouping features of the native window - // managers (GTK tends to not care either way, but Win32 definitely prefers a - // linear tab order). + // Add all RadioButtons in one pass, and then go back and create all the subtext + // objects. This ensures the radio buttons have consecutive tab order IDs, which + // is the "preferred" method when using grouping features of the native window + // managers (GTK tends to not care either way, but Win32 definitely prefers a + // linear tab order). - // first object has the group flag set to ensure it's the start of a radio group. - m_objects[0].LabelObj = new wxRadioButton(this, wxID_ANY, m_buttonStrings[0].Label, wxDefaultPosition, wxDefaultSize, wxRB_GROUP); - for (int i = 1; i < numbuttons; ++i) - m_objects[i].LabelObj = new wxRadioButton(this, wxID_ANY, m_buttonStrings[i].Label); + // first object has the group flag set to ensure it's the start of a radio group. + m_objects[0].LabelObj = new wxRadioButton(this, wxID_ANY, m_buttonStrings[0].Label, wxDefaultPosition, wxDefaultSize, wxRB_GROUP); + for (int i = 1; i < numbuttons; ++i) + m_objects[i].LabelObj = new wxRadioButton(this, wxID_ANY, m_buttonStrings[i].Label); - for (int i = 0; i < numbuttons; ++i) { - m_objects[i].SubTextObj = NULL; - if (m_buttonStrings[i].SubText.IsEmpty()) - continue; - m_objects[i].SubTextObj = new pxStaticText(this, m_buttonStrings[i].SubText, wxALIGN_LEFT); - } + for (int i = 0; i < numbuttons; ++i) + { + m_objects[i].SubTextObj = NULL; + if (m_buttonStrings[i].SubText.IsEmpty()) + continue; + m_objects[i].SubTextObj = new pxStaticText(this, m_buttonStrings[i].SubText, wxALIGN_LEFT); + } - pxAssert(GetSizer() != NULL); + pxAssert(GetSizer() != NULL); - for (int i = 0; i < numbuttons; ++i) { - *this += m_objects[i].LabelObj | pxSizerFlags::StdExpand(); + for (int i = 0; i < numbuttons; ++i) + { + *this += m_objects[i].LabelObj | pxSizerFlags::StdExpand(); - if (pxStaticText *subobj = m_objects[i].SubTextObj) { - *this += subobj | pxBorder(wxLEFT, m_Indentation).Expand(); - *this += 9 + m_padding.GetHeight(); - } - if (!m_buttonStrings[i].ToolTip.IsEmpty()) - _setToolTipImmediate(i, m_buttonStrings[i].ToolTip); - } + if (pxStaticText* subobj = m_objects[i].SubTextObj) + { + *this += subobj | pxBorder(wxLEFT, m_Indentation).Expand(); + *this += 9 + m_padding.GetHeight(); + } + if (!m_buttonStrings[i].ToolTip.IsEmpty()) + _setToolTipImmediate(i, m_buttonStrings[i].ToolTip); + } - _RealizeDefaultOption(); + _RealizeDefaultOption(); } -void pxRadioPanel::_setToolTipImmediate(int idx, const wxString &tip) +void pxRadioPanel::_setToolTipImmediate(int idx, const wxString& tip) { - if (wxRadioButton *woot = m_objects[idx].LabelObj) - woot->SetToolTip(tip); + if (wxRadioButton* woot = m_objects[idx].LabelObj) + woot->SetToolTip(tip); - if (pxStaticText *woot = m_objects[idx].SubTextObj) - woot->SetToolTip(tip); + if (pxStaticText* woot = m_objects[idx].SubTextObj) + woot->SetToolTip(tip); } // The SetToolTip API provided by this function applies the tooltip to both the radio // button and it's static subtext (if present), and performs word wrapping on platforms // that need it (eg mswindows). -pxRadioPanel &pxRadioPanel::SetToolTip(int idx, const wxString &tip) +pxRadioPanel& pxRadioPanel::SetToolTip(int idx, const wxString& tip) { - m_buttonStrings[idx].SetToolTip(tip); + m_buttonStrings[idx].SetToolTip(tip); - if (m_IsRealized) - _setToolTipImmediate(idx, tip); + if (m_IsRealized) + _setToolTipImmediate(idx, tip); - return *this; + return *this; } -pxRadioPanel &pxRadioPanel::SetSelection(int idx) +pxRadioPanel& pxRadioPanel::SetSelection(int idx) { - if (!VerifyRealizedState()) - return *this; + if (!VerifyRealizedState()) + return *this; - pxAssert(m_objects[idx].LabelObj != NULL); - m_objects[idx].LabelObj->SetValue(true); - return *this; + pxAssert(m_objects[idx].LabelObj != NULL); + m_objects[idx].LabelObj->SetValue(true); + return *this; } void pxRadioPanel::_RealizeDefaultOption() { - if (m_IsRealized && m_DefaultIdx != -1) { - wxFont def(GetFont()); - def.SetWeight(wxFONTWEIGHT_BOLD); - //def.SetStyle( wxFONTSTYLE_ITALIC ); - m_objects[m_DefaultIdx].LabelObj->SetFont(def); - m_objects[m_DefaultIdx].LabelObj->SetForegroundColour(wxColour(20, 128, 40)); - } + if (m_IsRealized && m_DefaultIdx != -1) + { + wxFont def(GetFont()); + def.SetWeight(wxFONTWEIGHT_BOLD); + //def.SetStyle( wxFONTSTYLE_ITALIC ); + m_objects[m_DefaultIdx].LabelObj->SetFont(def); + m_objects[m_DefaultIdx].LabelObj->SetForegroundColour(wxColour(20, 128, 40)); + } } // Highlights (bold) the text of the default radio. // Not intended for restoring default value at later time. -pxRadioPanel &pxRadioPanel::SetDefaultItem(int idx) +pxRadioPanel& pxRadioPanel::SetDefaultItem(int idx) { - if (idx == m_DefaultIdx) - return *this; + if (idx == m_DefaultIdx) + return *this; - if (m_IsRealized && m_DefaultIdx != -1) { - wxFont def(GetFont()); - m_objects[m_DefaultIdx].LabelObj->SetFont(def); - m_objects[m_DefaultIdx].LabelObj->SetForegroundColour(GetForegroundColour()); - } + if (m_IsRealized && m_DefaultIdx != -1) + { + wxFont def(GetFont()); + m_objects[m_DefaultIdx].LabelObj->SetFont(def); + m_objects[m_DefaultIdx].LabelObj->SetForegroundColour(GetForegroundColour()); + } - m_DefaultIdx = idx; - _RealizeDefaultOption(); + m_DefaultIdx = idx; + _RealizeDefaultOption(); - return *this; + return *this; } -pxRadioPanel &pxRadioPanel::EnableItem(int idx, bool enable) +pxRadioPanel& pxRadioPanel::EnableItem(int idx, bool enable) { - pxAssertDev(m_IsRealized, "RadioPanel must be realized first, prior to enabling or disabling individual items."); + pxAssertDev(m_IsRealized, "RadioPanel must be realized first, prior to enabling or disabling individual items."); - if (m_objects[idx].LabelObj) - m_objects[idx].LabelObj->Enable(enable); + if (m_objects[idx].LabelObj) + m_objects[idx].LabelObj->Enable(enable); - if (m_objects[idx].SubTextObj) - m_objects[idx].SubTextObj->Enable(enable); + if (m_objects[idx].SubTextObj) + m_objects[idx].SubTextObj->Enable(enable); - return *this; + return *this; } -const RadioPanelItem &pxRadioPanel::Item(int idx) const +const RadioPanelItem& pxRadioPanel::Item(int idx) const { - return m_buttonStrings[idx]; + return m_buttonStrings[idx]; } -RadioPanelItem &pxRadioPanel::Item(int idx) +RadioPanelItem& pxRadioPanel::Item(int idx) { - return m_buttonStrings[idx]; + return m_buttonStrings[idx]; } int pxRadioPanel::GetSelection() const { - if (!VerifyRealizedState()) - return 0; + if (!VerifyRealizedState()) + return 0; - for (uint i = 0; i < m_buttonStrings.size(); ++i) { - if (wxRadioButton *woot = m_objects[i].LabelObj) - if (woot->GetValue()) - return i; - } + for (uint i = 0; i < m_buttonStrings.size(); ++i) + { + if (wxRadioButton* woot = m_objects[i].LabelObj) + if (woot->GetValue()) + return i; + } - // Technically radio buttons should never allow for a case where none are selected. - // However it *can* happen on some platforms if the program code doesn't explicitly - // select one of the members of the group (which is, as far as I'm concerned, a - // programmer error!). so Assert here in such cases, and return 0 as the assumed - // default, so that calling code has a "valid" return code in release builds. + // Technically radio buttons should never allow for a case where none are selected. + // However it *can* happen on some platforms if the program code doesn't explicitly + // select one of the members of the group (which is, as far as I'm concerned, a + // programmer error!). so Assert here in such cases, and return 0 as the assumed + // default, so that calling code has a "valid" return code in release builds. - pxFailDev("No valid selection was found in this group!"); - return 0; + pxFailDev("No valid selection was found in this group!"); + return 0; } // Returns the wxWindowID for the currently selected radio button. wxWindowID pxRadioPanel::GetSelectionId() const { - if (!VerifyRealizedState()) - return 0; - return m_objects[GetSelection()].LabelObj->GetId(); + if (!VerifyRealizedState()) + return 0; + return m_objects[GetSelection()].LabelObj->GetId(); } bool pxRadioPanel::IsSelected(int idx) const { - if (!VerifyRealizedState()) - return false; - pxAssert(m_objects[idx].LabelObj != NULL); - return m_objects[idx].LabelObj->GetValue(); + if (!VerifyRealizedState()) + return false; + pxAssert(m_objects[idx].LabelObj != NULL); + return m_objects[idx].LabelObj->GetValue(); } -pxStaticText *pxRadioPanel::GetSubText(int idx) +pxStaticText* pxRadioPanel::GetSubText(int idx) { - if (!VerifyRealizedState()) - return NULL; - return m_objects[idx].SubTextObj; + if (!VerifyRealizedState()) + return NULL; + return m_objects[idx].SubTextObj; } -const pxStaticText *pxRadioPanel::GetSubText(int idx) const +const pxStaticText* pxRadioPanel::GetSubText(int idx) const { - if (!VerifyRealizedState()) - return NULL; - return m_objects[idx].SubTextObj; + if (!VerifyRealizedState()) + return NULL; + return m_objects[idx].SubTextObj; } -wxRadioButton *pxRadioPanel::GetButton(int idx) +wxRadioButton* pxRadioPanel::GetButton(int idx) { - if (!VerifyRealizedState()) - return NULL; - return m_objects[idx].LabelObj; + if (!VerifyRealizedState()) + return NULL; + return m_objects[idx].LabelObj; } -const wxRadioButton *pxRadioPanel::GetButton(int idx) const +const wxRadioButton* pxRadioPanel::GetButton(int idx) const { - if (!VerifyRealizedState()) - return NULL; - return m_objects[idx].LabelObj; + if (!VerifyRealizedState()) + return NULL; + return m_objects[idx].LabelObj; } diff --git a/common/pxRadioPanel.h b/common/pxRadioPanel.h index bf9772e2b7..516ad3232e 100644 --- a/common/pxRadioPanel.h +++ b/common/pxRadioPanel.h @@ -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& SetSubText(const wxString& text) + { + SubText = text; + return *this; + } - RadioPanelItem &SetInt(int intval) - { - SomeInt = intval; - return *this; - } + RadioPanelItem& SetInt(int intval) + { + SomeInt = intval; + return *this; + } - RadioPanelItem &SetPtr(void *ptrval) - { - SomePtr = ptrval; - 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 ButtonArray; - typedef SafeArray ButtonObjArray; + typedef std::vector ButtonArray; + typedef SafeArray 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 - pxRadioPanel(wxWindow *parent, const RadioPanelItem (&src)[size]) - : wxPanelWithHelpers(parent, wxVERTICAL) - { - Init(src, size); - } + template + 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() = default; + virtual ~pxRadioPanel() = default; - 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(); }; diff --git a/common/pxStaticText.cpp b/common/pxStaticText.cpp index 2d2aa58b61..71a91b5de0 100644 --- a/common/pxStaticText.cpp +++ b/common/pxStaticText.cpp @@ -20,33 +20,33 @@ // -------------------------------------------------------------------------------------- // pxStaticText (implementations) // -------------------------------------------------------------------------------------- -pxStaticText::pxStaticText(wxWindow *parent) - : _parent(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER) +pxStaticText::pxStaticText(wxWindow* parent) + : _parent(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER) { - m_align = wxALIGN_CENTRE_HORIZONTAL; - m_autowrap = true; - m_wrappedWidth = -1; - m_heightInLines = 1; + m_align = wxALIGN_CENTRE_HORIZONTAL; + m_autowrap = true; + m_wrappedWidth = -1; + m_heightInLines = 1; - SetPaddingDefaults(); + SetPaddingDefaults(); } -pxStaticText::pxStaticText(wxWindow *parent, const wxString &label, wxAlignment align) - : _parent(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER) +pxStaticText::pxStaticText(wxWindow* parent, const wxString& label, wxAlignment align) + : _parent(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER) { - m_heightInLines = 1; - m_align = align; + m_heightInLines = 1; + m_align = align; - SetPaddingDefaults(); - Init(label); + SetPaddingDefaults(); + Init(label); } -void pxStaticText::Init(const wxString &label) +void pxStaticText::Init(const wxString& label) { - m_autowrap = true; - m_wrappedWidth = -1; - m_label = label; - Bind(wxEVT_PAINT, &pxStaticText::paintEvent, this); + m_autowrap = true; + m_wrappedWidth = -1; + m_label = label; + Bind(wxEVT_PAINT, &pxStaticText::paintEvent, this); } // we need to refresh the window after changing its size as the standard @@ -54,328 +54,338 @@ void pxStaticText::Init(const wxString &label) // the control is expanded to fit -- ie the control's size changes but the position does not) void pxStaticText::DoSetSize(int x, int y, int w, int h, int sizeFlags) { - _parent::DoSetSize(x, y, w, h, sizeFlags); - Refresh(); + _parent::DoSetSize(x, y, w, h, sizeFlags); + Refresh(); } void pxStaticText::SetPaddingDefaults() { - m_paddingPix_horiz = 7; - m_paddingPix_vert = 1; + m_paddingPix_horiz = 7; + m_paddingPix_vert = 1; - m_paddingPct_horiz = 0.0f; - m_paddingPct_vert = 0.0f; + m_paddingPct_horiz = 0.0f; + m_paddingPct_vert = 0.0f; } -pxStaticText &pxStaticText::SetMinWidth(int width) +pxStaticText& pxStaticText::SetMinWidth(int width) { - SetMinSize(wxSize(width, GetMinHeight())); - return *this; + SetMinSize(wxSize(width, GetMinHeight())); + return *this; } -pxStaticText &pxStaticText::SetMinHeight(int height) +pxStaticText& pxStaticText::SetMinHeight(int height) { - SetMinSize(wxSize(GetMinWidth(), height)); - return *this; + SetMinSize(wxSize(GetMinWidth(), height)); + return *this; } -pxStaticText &pxStaticText::SetHeight(int lines) +pxStaticText& pxStaticText::SetHeight(int lines) { - if (!pxAssert(lines > 0)) - lines = 2; - m_heightInLines = lines; + if (!pxAssert(lines > 0)) + lines = 2; + m_heightInLines = lines; - const int newHeight = (pxGetCharHeight(this) * m_heightInLines) + (m_paddingPix_vert * 2); - SetMinSize(wxSize(GetMinWidth(), newHeight)); + const int newHeight = (pxGetCharHeight(this) * m_heightInLines) + (m_paddingPix_vert * 2); + SetMinSize(wxSize(GetMinWidth(), newHeight)); - return *this; + return *this; } -pxStaticText &pxStaticText::Align(wxAlignment align) +pxStaticText& pxStaticText::Align(wxAlignment align) { - m_align = align; - return *this; + m_align = align; + return *this; } -pxStaticText &pxStaticText::Bold() +pxStaticText& pxStaticText::Bold() { - wxFont bold(GetFont()); - bold.SetWeight(wxFONTWEIGHT_BOLD); - SetFont(bold); - return *this; + wxFont bold(GetFont()); + bold.SetWeight(wxFONTWEIGHT_BOLD); + SetFont(bold); + return *this; } -pxStaticText &pxStaticText::PaddingPixH(int pixels) +pxStaticText& pxStaticText::PaddingPixH(int pixels) { - m_paddingPix_horiz = pixels; - UpdateWrapping(false); - Refresh(); - return *this; + m_paddingPix_horiz = pixels; + UpdateWrapping(false); + Refresh(); + return *this; } -pxStaticText &pxStaticText::PaddingPixV(int pixels) +pxStaticText& pxStaticText::PaddingPixV(int pixels) { - m_paddingPix_vert = pixels; - Refresh(); - return *this; + m_paddingPix_vert = pixels; + Refresh(); + return *this; } -pxStaticText &pxStaticText::PaddingPctH(float pct) +pxStaticText& pxStaticText::PaddingPctH(float pct) { - pxAssert(pct < 0.5); + pxAssert(pct < 0.5); - m_paddingPct_horiz = pct; - UpdateWrapping(false); - Refresh(); - return *this; + m_paddingPct_horiz = pct; + UpdateWrapping(false); + Refresh(); + return *this; } -pxStaticText &pxStaticText::PaddingPctV(float pct) +pxStaticText& pxStaticText::PaddingPctV(float pct) { - pxAssert(pct < 0.5); + pxAssert(pct < 0.5); - m_paddingPct_vert = pct; - Refresh(); - return *this; + m_paddingPct_vert = pct; + Refresh(); + return *this; } -pxStaticText &pxStaticText::Unwrapped() +pxStaticText& pxStaticText::Unwrapped() { - m_autowrap = false; - UpdateWrapping(false); - return *this; + m_autowrap = false; + UpdateWrapping(false); + return *this; } int pxStaticText::calcPaddingWidth(int newWidth) const { - return (int)(newWidth * m_paddingPct_horiz * 2) + (m_paddingPix_horiz * 2); + return (int)(newWidth * m_paddingPct_horiz * 2) + (m_paddingPix_horiz * 2); } int pxStaticText::calcPaddingHeight(int newHeight) const { - return (int)(newHeight * m_paddingPct_vert * 2) + (m_paddingPix_vert * 2); + return (int)(newHeight * m_paddingPct_vert * 2) + (m_paddingPix_vert * 2); } -wxSize pxStaticText::GetBestWrappedSize(const wxClientDC &dc) const +wxSize pxStaticText::GetBestWrappedSize(const wxClientDC& dc) const { - pxAssert(m_autowrap); + pxAssert(m_autowrap); - // Find an ideal(-ish) width, based on a search of all parent controls and their - // valid Minimum sizes. + // Find an ideal(-ish) width, based on a search of all parent controls and their + // valid Minimum sizes. - int idealWidth = wxDefaultCoord; - int parentalAdjust = 0; - double parentalFactor = 1.0; - const wxWindow *millrun = this; + int idealWidth = wxDefaultCoord; + int parentalAdjust = 0; + double parentalFactor = 1.0; + const wxWindow* millrun = this; - while (millrun) { - // IMPORTANT : wxWizard changes its min size and then expects everything else - // to play nice and NOT resize according to the new min size. (wtf stupid) - // Anyway, this fixes it -- ignore min size specifier on wxWizard! - if (wxIsKindOf(millrun, wxWizard)) - break; + while (millrun) + { + // IMPORTANT : wxWizard changes its min size and then expects everything else + // to play nice and NOT resize according to the new min size. (wtf stupid) + // Anyway, this fixes it -- ignore min size specifier on wxWizard! + if (wxIsKindOf(millrun, wxWizard)) + break; - int min = (int)((millrun->GetMinWidth() - parentalAdjust) * parentalFactor); + int min = (int)((millrun->GetMinWidth() - parentalAdjust) * parentalFactor); - if (min > 0 && ((idealWidth < 0) || (min < idealWidth))) { - idealWidth = min; - } + if (min > 0 && ((idealWidth < 0) || (min < idealWidth))) + { + idealWidth = min; + } - parentalAdjust += pxSizerFlags::StdPadding * 2; - millrun = millrun->GetParent(); - } + parentalAdjust += pxSizerFlags::StdPadding * 2; + millrun = millrun->GetParent(); + } - if (idealWidth <= 0) { - // FIXME: The minimum size of this control is unknown, so let's just pick a guess based on - // the size of the user's display area. + if (idealWidth <= 0) + { + // FIXME: The minimum size of this control is unknown, so let's just pick a guess based on + // the size of the user's display area. - idealWidth = (int)(wxGetDisplaySize().GetWidth() * 0.66) - (parentalAdjust * 2); - } + idealWidth = (int)(wxGetDisplaySize().GetWidth() * 0.66) - (parentalAdjust * 2); + } - return dc.GetMultiLineTextExtent(pxTextWrapper().Wrap(this, m_label, idealWidth - calcPaddingWidth(idealWidth)).GetResult()); + return dc.GetMultiLineTextExtent(pxTextWrapper().Wrap(this, m_label, idealWidth - calcPaddingWidth(idealWidth)).GetResult()); } -pxStaticText &pxStaticText::WrapAt(int width) +pxStaticText& pxStaticText::WrapAt(int width) { - m_autowrap = false; + m_autowrap = false; - if ((width <= 1) || (width == m_wrappedWidth)) - return *this; + if ((width <= 1) || (width == m_wrappedWidth)) + return *this; - wxString wrappedLabel; - m_wrappedWidth = width; + wxString wrappedLabel; + m_wrappedWidth = width; - if (width > 1) - wrappedLabel = pxTextWrapper().Wrap(this, m_label, width).GetResult(); + if (width > 1) + wrappedLabel = pxTextWrapper().Wrap(this, m_label, width).GetResult(); - if (m_wrappedLabel != wrappedLabel) { - m_wrappedLabel = wrappedLabel; - wxSize area = wxClientDC(this).GetMultiLineTextExtent(m_wrappedLabel); - SetMinSize(wxSize( - area.GetWidth() + calcPaddingWidth(area.GetWidth()), - area.GetHeight() + calcPaddingHeight(area.GetHeight()))); - } - return *this; + if (m_wrappedLabel != wrappedLabel) + { + m_wrappedLabel = wrappedLabel; + wxSize area = wxClientDC(this).GetMultiLineTextExtent(m_wrappedLabel); + SetMinSize(wxSize( + area.GetWidth() + calcPaddingWidth(area.GetWidth()), + area.GetHeight() + calcPaddingHeight(area.GetHeight()))); + } + return *this; } bool pxStaticText::_updateWrapping(bool textChanged) { - if (!m_autowrap) { - //m_wrappedLabel = wxEmptyString; - //m_wrappedWidth = -1; - return false; - } + if (!m_autowrap) + { + //m_wrappedLabel = wxEmptyString; + //m_wrappedWidth = -1; + return false; + } - wxString wrappedLabel; - int newWidth = GetSize().GetWidth(); + wxString wrappedLabel; + int newWidth = GetSize().GetWidth(); - if (!textChanged && (newWidth == m_wrappedWidth)) - return false; + if (!textChanged && (newWidth == m_wrappedWidth)) + return false; - // Note: during various stages of sizer-calc, width can be 1, 0, or -1. - // We ignore wrapping in these cases. (the PaintEvent also checks the wrapping - // and updates it if needed, in case the control's size isn't figured out prior - // to being painted). + // Note: during various stages of sizer-calc, width can be 1, 0, or -1. + // We ignore wrapping in these cases. (the PaintEvent also checks the wrapping + // and updates it if needed, in case the control's size isn't figured out prior + // to being painted). - m_wrappedWidth = newWidth; - if (m_wrappedWidth > 1) - wrappedLabel = pxTextWrapper().Wrap(this, m_label, m_wrappedWidth).GetResult(); + m_wrappedWidth = newWidth; + if (m_wrappedWidth > 1) + wrappedLabel = pxTextWrapper().Wrap(this, m_label, m_wrappedWidth).GetResult(); - if (m_wrappedLabel == wrappedLabel) - return false; - m_wrappedLabel = wrappedLabel; + if (m_wrappedLabel == wrappedLabel) + return false; + m_wrappedLabel = wrappedLabel; - return true; + return true; } void pxStaticText::UpdateWrapping(bool textChanged) { - if (_updateWrapping(textChanged)) - Refresh(); + if (_updateWrapping(textChanged)) + Refresh(); } -void pxStaticText::SetLabel(const wxString &label) +void pxStaticText::SetLabel(const wxString& label) { - const bool labelChanged(label != m_label); - if (labelChanged) { - m_label = label; - Refresh(); - } + const bool labelChanged(label != m_label); + if (labelChanged) + { + m_label = label; + Refresh(); + } - // Always update wrapping, in case window width or something else also changed. - UpdateWrapping(labelChanged); - InvalidateBestSize(); + // Always update wrapping, in case window width or something else also changed. + UpdateWrapping(labelChanged); + InvalidateBestSize(); } wxFont pxStaticText::GetFontOk() const { - wxFont font(GetFont()); - if (!font.Ok()) - return wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); - return font; + wxFont font(GetFont()); + if (!font.Ok()) + return wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + return font; } bool pxStaticText::Enable(bool enabled) { - if (_parent::Enable(enabled)) { - Refresh(); - return true; - } - return false; + if (_parent::Enable(enabled)) + { + Refresh(); + return true; + } + return false; } -void pxStaticText::paintEvent(wxPaintEvent &evt) +void pxStaticText::paintEvent(wxPaintEvent& evt) { - wxPaintDC dc(this); - const int dcWidth = dc.GetSize().GetWidth(); - const int dcHeight = dc.GetSize().GetHeight(); - if (dcWidth < 1) - return; - dc.SetFont(GetFontOk()); + wxPaintDC dc(this); + const int dcWidth = dc.GetSize().GetWidth(); + const int dcHeight = dc.GetSize().GetHeight(); + if (dcWidth < 1) + return; + dc.SetFont(GetFontOk()); - if (IsEnabled()) - dc.SetTextForeground(GetForegroundColour()); - else - dc.SetTextForeground(*wxLIGHT_GREY); + if (IsEnabled()) + dc.SetTextForeground(GetForegroundColour()); + else + dc.SetTextForeground(*wxLIGHT_GREY); - pxWindowTextWriter writer(dc); - writer.Align(m_align); + pxWindowTextWriter writer(dc); + writer.Align(m_align); - const wxString &label(m_autowrap ? m_wrappedLabel : m_label); - if (m_autowrap) - _updateWrapping(false); + const wxString& label(m_autowrap ? m_wrappedLabel : m_label); + if (m_autowrap) + _updateWrapping(false); - int tWidth, tHeight; - dc.GetMultiLineTextExtent(label, &tWidth, &tHeight); + int tWidth, tHeight; + dc.GetMultiLineTextExtent(label, &tWidth, &tHeight); - writer.Align(m_align); - if (m_align & wxALIGN_CENTER_VERTICAL) - writer.SetY((dcHeight - tHeight) / 2); - else - writer.SetY((int)(dcHeight * m_paddingPct_vert) + m_paddingPix_vert); + writer.Align(m_align); + if (m_align & wxALIGN_CENTER_VERTICAL) + writer.SetY((dcHeight - tHeight) / 2); + else + writer.SetY((int)(dcHeight * m_paddingPct_vert) + m_paddingPix_vert); - writer.WriteLn(label); // without formatting please. + writer.WriteLn(label); // without formatting please. - //dc.SetBrush( *wxTRANSPARENT_BRUSH ); - //dc.DrawRectangle(wxPoint(), dc.GetSize()); + //dc.SetBrush( *wxTRANSPARENT_BRUSH ); + //dc.DrawRectangle(wxPoint(), dc.GetSize()); } // Overloaded form wxPanel and friends. wxSize pxStaticText::DoGetBestSize() const { - wxClientDC dc(const_cast(this)); - dc.SetFont(GetFontOk()); + wxClientDC dc(const_cast(this)); + dc.SetFont(GetFontOk()); - wxSize best; + wxSize best; - if (m_autowrap) { - best = GetBestWrappedSize(dc); - //best.x = wxDefaultCoord; - } else { - // No autowrapping, so we can force a specific size here! - best = dc.GetMultiLineTextExtent(GetLabel()); - best.x += calcPaddingWidth(best.x); - } + if (m_autowrap) + { + best = GetBestWrappedSize(dc); + //best.x = wxDefaultCoord; + } + else + { + // No autowrapping, so we can force a specific size here! + best = dc.GetMultiLineTextExtent(GetLabel()); + best.x += calcPaddingWidth(best.x); + } - best.y += calcPaddingHeight(best.y); + best.y += calcPaddingHeight(best.y); - CacheBestSize(best); - return best; + CacheBestSize(best); + return best; } // -------------------------------------------------------------------------------------- // pxStaticHeading (implementations) // -------------------------------------------------------------------------------------- -pxStaticHeading::pxStaticHeading(wxWindow *parent, const wxString &label) - : _parent(parent) +pxStaticHeading::pxStaticHeading(wxWindow* parent, const wxString& label) + : _parent(parent) { - m_align = wxALIGN_CENTER; + m_align = wxALIGN_CENTER; - SetPaddingDefaults(); - Init(label); + SetPaddingDefaults(); + Init(label); } void pxStaticHeading::SetPaddingDefaults() { - m_paddingPix_horiz = 4; - m_paddingPix_vert = 1; + m_paddingPix_horiz = 4; + m_paddingPix_vert = 1; - m_paddingPct_horiz = 0.08f; - m_paddingPct_vert = 0.0f; + m_paddingPct_horiz = 0.08f; + m_paddingPct_vert = 0.0f; } -void operator+=(wxSizer &target, pxStaticText *src) +void operator+=(wxSizer& target, pxStaticText* src) { - if (src) - target.Add(src, pxExpand); + if (src) + target.Add(src, pxExpand); } -void operator+=(wxSizer &target, pxStaticText &src) +void operator+=(wxSizer& target, pxStaticText& src) { - target.Add(&src, pxExpand); + target.Add(&src, pxExpand); } -void operator+=(wxSizer *target, pxStaticText &src) +void operator+=(wxSizer* target, pxStaticText& src) { - target->Add(&src, pxExpand); + target->Add(&src, pxExpand); } diff --git a/common/pxStaticText.h b/common/pxStaticText.h index 0b1e88b15e..13f1d63aa1 100644 --- a/common/pxStaticText.h +++ b/common/pxStaticText.h @@ -34,92 +34,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() = default; + 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() = default; - 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() = default; + pxStaticHeading(wxWindow* parent = NULL, const wxString& label = wxEmptyString); + pxStaticHeading(wxWindow* parent, int heightInLines, const wxString& label = wxEmptyString); + virtual ~pxStaticHeading() = default; 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 &src) +inline void operator+=(wxSizer& target, const pxWindowAndFlags& src) { - target.Add(src.window, src.flags); + target.Add(src.window, src.flags); } diff --git a/common/pxStreams.cpp b/common/pxStreams.cpp index 3f930bb903..3b8a058d53 100644 --- a/common/pxStreams.cpp +++ b/common/pxStreams.cpp @@ -23,22 +23,22 @@ // -------------------------------------------------------------------------------------- // pxStreamBase (implementations) // -------------------------------------------------------------------------------------- -pxStreamBase::pxStreamBase(const wxString &filename) - : m_filename(filename) +pxStreamBase::pxStreamBase(const wxString& filename) + : m_filename(filename) { } bool pxStreamBase::IsOk() const { - wxStreamBase *woot = GetWxStreamBase(); - return woot && woot->IsOk(); + wxStreamBase* woot = GetWxStreamBase(); + return woot && woot->IsOk(); } wxFileOffset pxStreamBase::Length() const { - if (!GetWxStreamBase()) - return 0; - return GetWxStreamBase()->GetLength(); + if (!GetWxStreamBase()) + return 0; + return GetWxStreamBase()->GetLength(); } // -------------------------------------------------------------------------------------- @@ -47,115 +47,117 @@ wxFileOffset pxStreamBase::Length() const // Interface for reading data from a gzip stream. // -pxInputStream::pxInputStream(const wxString &filename, std::unique_ptr &input) - : pxStreamBase(filename) - , m_stream_in(std::move(input)) +pxInputStream::pxInputStream(const wxString& filename, std::unique_ptr& input) + : pxStreamBase(filename) + , m_stream_in(std::move(input)) { } -pxInputStream::pxInputStream(const wxString &filename, wxInputStream *input) - : pxStreamBase(filename) - , m_stream_in(input) +pxInputStream::pxInputStream(const wxString& filename, wxInputStream* input) + : pxStreamBase(filename) + , m_stream_in(input) { } -wxStreamBase *pxInputStream::GetWxStreamBase() const { return m_stream_in.get(); } +wxStreamBase* pxInputStream::GetWxStreamBase() const { return m_stream_in.get(); } wxFileOffset pxInputStream::Tell() const { - return m_stream_in->TellI(); + return m_stream_in->TellI(); } wxFileOffset pxInputStream::Seek(wxFileOffset ofs, wxSeekMode mode) { - return m_stream_in->SeekI(ofs, mode); + return m_stream_in->SeekI(ofs, mode); } -void pxInputStream::SetStream(const wxString &filename, std::unique_ptr &stream) +void pxInputStream::SetStream(const wxString& filename, std::unique_ptr& stream) { - m_filename = filename; - m_stream_in = std::move(stream); + m_filename = filename; + m_stream_in = std::move(stream); } -void pxInputStream::SetStream(const wxString &filename, wxInputStream *stream) +void pxInputStream::SetStream(const wxString& filename, wxInputStream* stream) { - m_filename = filename; - m_stream_in = std::unique_ptr(stream); + m_filename = filename; + m_stream_in = std::unique_ptr(stream); } -void pxInputStream::Read(void *dest, size_t size) +void pxInputStream::Read(void* dest, size_t size) { - m_stream_in->Read(dest, size); - if (m_stream_in->GetLastError() == wxSTREAM_READ_ERROR) { - int err = errno; - if (!err) - throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot read from file (bad file handle?)"); + m_stream_in->Read(dest, size); + if (m_stream_in->GetLastError() == wxSTREAM_READ_ERROR) + { + int err = errno; + if (!err) + throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot read from file (bad file handle?)"); - ScopedExcept ex(Exception::FromErrno(m_filename, err)); - ex->SetDiagMsg(L"cannot read from file: " + ex->DiagMsg()); - ex->Rethrow(); - } + ScopedExcept ex(Exception::FromErrno(m_filename, err)); + ex->SetDiagMsg(L"cannot read from file: " + ex->DiagMsg()); + ex->Rethrow(); + } - // IMPORTANT! The underlying file/source Eof() stuff is not really reliable, so we - // must always use the explicit check against the number of bytes read to determine - // end-of-stream conditions. + // IMPORTANT! The underlying file/source Eof() stuff is not really reliable, so we + // must always use the explicit check against the number of bytes read to determine + // end-of-stream conditions. - if ((size_t)m_stream_in->LastRead() < size) - throw Exception::EndOfStream(m_filename); + if ((size_t)m_stream_in->LastRead() < size) + throw Exception::EndOfStream(m_filename); } // -------------------------------------------------------------------------------------- // pxOutputStream // -------------------------------------------------------------------------------------- -pxOutputStream::pxOutputStream(const wxString &filename, std::unique_ptr &output) - : pxStreamBase(filename) - , m_stream_out(std::move(output)) +pxOutputStream::pxOutputStream(const wxString& filename, std::unique_ptr& output) + : pxStreamBase(filename) + , m_stream_out(std::move(output)) { } -pxOutputStream::pxOutputStream(const wxString &filename, wxOutputStream *output) - : pxStreamBase(filename) - , m_stream_out(output) +pxOutputStream::pxOutputStream(const wxString& filename, wxOutputStream* output) + : pxStreamBase(filename) + , m_stream_out(output) { } -wxStreamBase *pxOutputStream::GetWxStreamBase() const { return m_stream_out.get(); } +wxStreamBase* pxOutputStream::GetWxStreamBase() const { return m_stream_out.get(); } wxFileOffset pxOutputStream::Tell() const { - return m_stream_out->TellO(); + return m_stream_out->TellO(); } wxFileOffset pxOutputStream::Seek(wxFileOffset ofs, wxSeekMode mode) { - return m_stream_out->SeekO(ofs, mode); + return m_stream_out->SeekO(ofs, mode); } -void pxOutputStream::SetStream(const wxString &filename, std::unique_ptr &stream) +void pxOutputStream::SetStream(const wxString& filename, std::unique_ptr& stream) { - m_filename = filename; - m_stream_out = std::move(stream); + m_filename = filename; + m_stream_out = std::move(stream); } -void pxOutputStream::SetStream(const wxString &filename, wxOutputStream *stream) +void pxOutputStream::SetStream(const wxString& filename, wxOutputStream* stream) { - m_filename = filename; - m_stream_out = std::unique_ptr(stream); + m_filename = filename; + m_stream_out = std::unique_ptr(stream); } -void pxOutputStream::Write(const void *src, size_t size) +void pxOutputStream::Write(const void* src, size_t size) { - m_stream_out->Write(src, size); - if (m_stream_out->GetLastError() == wxSTREAM_WRITE_ERROR) { - int err = errno; - if (!err) - throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot write to file/stream."); + m_stream_out->Write(src, size); + if (m_stream_out->GetLastError() == wxSTREAM_WRITE_ERROR) + { + int err = errno; + if (!err) + throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot write to file/stream."); - ScopedExcept ex(Exception::FromErrno(m_filename, err)); - ex->SetDiagMsg(L"Cannot write to file: " + ex->DiagMsg()); - ex->Rethrow(); - } + ScopedExcept ex(Exception::FromErrno(m_filename, err)); + ex->SetDiagMsg(L"Cannot write to file: " + ex->DiagMsg()); + ex->Rethrow(); + } } // -------------------------------------------------------------------------------------- @@ -163,89 +165,93 @@ void pxOutputStream::Write(const void *src, size_t size) // -------------------------------------------------------------------------------------- // Returns TRUE if the source is UTF8, or FALSE if it's just ASCII crap. -bool pxReadLine(wxInputStream &input, std::string &dest) +bool pxReadLine(wxInputStream& input, std::string& dest) { - dest.clear(); - bool isUTF8 = false; - while (true) { - char c; - input.Read(&c, sizeof(c)); - if (c == 0) - break; - if (input.Eof()) - break; - if (c == '\n') - break; // eat on UNIX - if (c == '\r') { - input.Read(&c, sizeof(c)); - if (c == 0) - break; - if (input.Eof()) - break; - if (c == '\n') - break; + dest.clear(); + bool isUTF8 = false; + while (true) + { + char c; + input.Read(&c, sizeof(c)); + if (c == 0) + break; + if (input.Eof()) + break; + if (c == '\n') + break; // eat on UNIX + if (c == '\r') + { + input.Read(&c, sizeof(c)); + if (c == 0) + break; + if (input.Eof()) + break; + if (c == '\n') + break; - input.Ungetch(c); - break; - } - dest += c; - if (c & 0x80) - isUTF8 = true; - } + input.Ungetch(c); + break; + } + dest += c; + if (c & 0x80) + isUTF8 = true; + } - return isUTF8; + return isUTF8; } -void pxReadLine(wxInputStream &input, wxString &dest, std::string &intermed) +void pxReadLine(wxInputStream& input, wxString& dest, std::string& intermed) { - dest.clear(); - if (pxReadLine(input, intermed)) - dest = fromUTF8(intermed.c_str()); - else { - // Optimized ToAscii conversion. - // wx3.0 : NOT COMPATIBLE!! (on linux anyway) - const char *ascii = intermed.c_str(); - while (*ascii != 0) - dest += (wchar_t)(unsigned char)*ascii++; - } + dest.clear(); + if (pxReadLine(input, intermed)) + dest = fromUTF8(intermed.c_str()); + else + { + // Optimized ToAscii conversion. + // wx3.0 : NOT COMPATIBLE!! (on linux anyway) + const char* ascii = intermed.c_str(); + while (*ascii != 0) + dest += (wchar_t)(unsigned char)*ascii++; + } } -void pxReadLine(wxInputStream &input, wxString &dest) +void pxReadLine(wxInputStream& input, wxString& dest) { - std::string line; - pxReadLine(input, dest, line); + std::string line; + pxReadLine(input, dest, line); } -wxString pxReadLine(wxInputStream &input) +wxString pxReadLine(wxInputStream& input) { - wxString result; - pxReadLine(input, result); - return result; + wxString result; + pxReadLine(input, result); + return result; } -void pxWriteLine(wxOutputStream &output) +void pxWriteLine(wxOutputStream& output) { - output.Write("\n", 1); + output.Write("\n", 1); } -void pxWriteLine(wxOutputStream &output, const wxString &text) +void pxWriteLine(wxOutputStream& output, const wxString& text) { - if (!text.IsEmpty()) { - pxToUTF8 utf8(text); - output.Write(utf8, utf8.Length()); - } - pxWriteLine(output); + if (!text.IsEmpty()) + { + pxToUTF8 utf8(text); + output.Write(utf8, utf8.Length()); + } + pxWriteLine(output); } -void pxWriteMultiline(wxOutputStream &output, const wxString &src) +void pxWriteMultiline(wxOutputStream& output, const wxString& src) { - if (src.IsEmpty()) - return; + if (src.IsEmpty()) + return; - wxString result(src); - result.Replace(L"\r\n", L"\n"); - result.Replace(L"\r", L"\n"); + wxString result(src); + result.Replace(L"\r\n", L"\n"); + result.Replace(L"\r", L"\n"); - pxToUTF8 utf8(result); - output.Write(utf8, utf8.Length()); + pxToUTF8 utf8(result); + output.Write(utf8, utf8.Length()); } diff --git a/common/pxStreams.h b/common/pxStreams.h index f3463ff127..e94f5d82c5 100644 --- a/common/pxStreams.h +++ b/common/pxStreams.h @@ -25,28 +25,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() = default; + pxStreamBase(const wxString& filename); + virtual ~pxStreamBase() = default; - // 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; } }; @@ -55,33 +55,33 @@ public: // -------------------------------------------------------------------------------------- class pxOutputStream : public pxStreamBase { - DeclareNoncopyableObject(pxOutputStream); + DeclareNoncopyableObject(pxOutputStream); protected: - std::unique_ptr m_stream_out; + std::unique_ptr m_stream_out; public: - pxOutputStream(const wxString &filename, std::unique_ptr &output); - pxOutputStream(const wxString &filename, wxOutputStream *output); + pxOutputStream(const wxString& filename, std::unique_ptr& output); + pxOutputStream(const wxString& filename, wxOutputStream* output); - virtual ~pxOutputStream() = default; - virtual void Write(const void *data, size_t size); + virtual ~pxOutputStream() = default; + virtual void Write(const void* data, size_t size); - void SetStream(const wxString &filename, std::unique_ptr &stream); - void SetStream(const wxString &filename, wxOutputStream *stream); + void SetStream(const wxString& filename, std::unique_ptr& stream); + void SetStream(const wxString& filename, wxOutputStream* stream); - void Close() { m_stream_out = nullptr; } + void Close() { m_stream_out = nullptr; } - virtual wxStreamBase *GetWxStreamBase() const; + virtual wxStreamBase* GetWxStreamBase() const; - template - void Write(const T &data) - { - Write(&data, sizeof(data)); - } + template + void Write(const T& data) + { + Write(&data, sizeof(data)); + } - wxFileOffset Tell() const; - wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart); + wxFileOffset Tell() const; + wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart); }; // -------------------------------------------------------------------------------------- @@ -89,31 +89,31 @@ public: // -------------------------------------------------------------------------------------- class pxInputStream : public pxStreamBase { - DeclareNoncopyableObject(pxInputStream); + DeclareNoncopyableObject(pxInputStream); protected: - std::unique_ptr m_stream_in; + std::unique_ptr m_stream_in; public: - pxInputStream(const wxString &filename, std::unique_ptr &input); - pxInputStream(const wxString &filename, wxInputStream *input); + pxInputStream(const wxString& filename, std::unique_ptr& input); + pxInputStream(const wxString& filename, wxInputStream* input); - virtual ~pxInputStream() = default; - virtual void Read(void *dest, size_t size); + virtual ~pxInputStream() = default; + virtual void Read(void* dest, size_t size); - void SetStream(const wxString &filename, std::unique_ptr &stream); - void SetStream(const wxString &filename, wxInputStream *stream); + void SetStream(const wxString& filename, std::unique_ptr& stream); + void SetStream(const wxString& filename, wxInputStream* stream); - void Close() { m_stream_in = nullptr; } + void Close() { m_stream_in = nullptr; } - virtual wxStreamBase *GetWxStreamBase() const; + virtual wxStreamBase* GetWxStreamBase() const; - template - void Read(T &dest) - { - Read(&dest, sizeof(dest)); - } + template + void Read(T& dest) + { + Read(&dest, sizeof(dest)); + } - wxFileOffset Tell() const; - wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart); + wxFileOffset Tell() const; + wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart); }; diff --git a/common/pxTranslate.cpp b/common/pxTranslate.cpp index f08a4c0870..378411e8e1 100644 --- a/common/pxTranslate.cpp +++ b/common/pxTranslate.cpp @@ -25,12 +25,12 @@ bool pxIsEnglish(int id) // pxExpandMsg -- an Iconized Text Translator // Was replaced by a standard implementation of wxGetTranslation // -------------------------------------------------------------------------------------- -const wxChar *__fastcall pxExpandMsg(const wxChar *message) +const wxChar* __fastcall pxExpandMsg(const wxChar* message) { return wxGetTranslation(message).wc_str(); } -const wxChar *__fastcall pxGetTranslation(const wxChar *message) +const wxChar* __fastcall pxGetTranslation(const wxChar* message) { return wxGetTranslation(message).wc_str(); } diff --git a/common/pxWindowTextWriter.cpp b/common/pxWindowTextWriter.cpp index 1211527c47..8378b9c122 100644 --- a/common/pxWindowTextWriter.cpp +++ b/common/pxWindowTextWriter.cpp @@ -20,137 +20,140 @@ // -------------------------------------------------------------------------------------- // pxWindowTextWriter Implementations // -------------------------------------------------------------------------------------- -pxWindowTextWriter::pxWindowTextWriter(wxDC &dc) - : m_dc(dc) +pxWindowTextWriter::pxWindowTextWriter(wxDC& dc) + : m_dc(dc) { - m_curpos = wxPoint(); - m_align = wxALIGN_CENTER; - m_leading = 0; + m_curpos = wxPoint(); + m_align = wxALIGN_CENTER; + m_leading = 0; - OnFontChanged(); + OnFontChanged(); } void pxWindowTextWriter::OnFontChanged() { } -pxWindowTextWriter &pxWindowTextWriter::SetWeight(wxFontWeight weight) +pxWindowTextWriter& pxWindowTextWriter::SetWeight(wxFontWeight weight) { - wxFont curfont(m_dc.GetFont()); - curfont.SetWeight(weight); - m_dc.SetFont(curfont); + wxFont curfont(m_dc.GetFont()); + curfont.SetWeight(weight); + m_dc.SetFont(curfont); - return *this; + return *this; } -pxWindowTextWriter &pxWindowTextWriter::SetStyle(wxFontStyle style) +pxWindowTextWriter& pxWindowTextWriter::SetStyle(wxFontStyle style) { - wxFont curfont(m_dc.GetFont()); - curfont.SetStyle(style); - m_dc.SetFont(curfont); - return *this; + wxFont curfont(m_dc.GetFont()); + curfont.SetStyle(style); + m_dc.SetFont(curfont); + return *this; } -pxWindowTextWriter &pxWindowTextWriter::Normal() +pxWindowTextWriter& pxWindowTextWriter::Normal() { - wxFont curfont(m_dc.GetFont()); - curfont.SetStyle(wxFONTSTYLE_NORMAL); - curfont.SetWeight(wxFONTWEIGHT_NORMAL); - m_dc.SetFont(curfont); + wxFont curfont(m_dc.GetFont()); + curfont.SetStyle(wxFONTSTYLE_NORMAL); + curfont.SetWeight(wxFONTWEIGHT_NORMAL); + m_dc.SetFont(curfont); - return *this; + return *this; } -pxWindowTextWriter &pxWindowTextWriter::SetPos(const wxPoint &pos) +pxWindowTextWriter& pxWindowTextWriter::SetPos(const wxPoint& pos) { - m_curpos = pos; - return *this; + m_curpos = pos; + return *this; } -pxWindowTextWriter &pxWindowTextWriter::MovePos(const wxSize &delta) +pxWindowTextWriter& pxWindowTextWriter::MovePos(const wxSize& delta) { - m_curpos += delta; - return *this; + m_curpos += delta; + return *this; } -pxWindowTextWriter &pxWindowTextWriter::SetY(int ypos) +pxWindowTextWriter& pxWindowTextWriter::SetY(int ypos) { - m_curpos.y = ypos; - return *this; + m_curpos.y = ypos; + return *this; } -pxWindowTextWriter &pxWindowTextWriter::MoveY(int ydelta) +pxWindowTextWriter& pxWindowTextWriter::MoveY(int ydelta) { - m_curpos.y += ydelta; - return *this; + m_curpos.y += ydelta; + return *this; } -void pxWindowTextWriter::_DoWriteLn(const wxString &msg) +void pxWindowTextWriter::_DoWriteLn(const wxString& msg) { - int tWidth, tHeight; - m_dc.GetMultiLineTextExtent(msg, &tWidth, &tHeight); + int tWidth, tHeight; + m_dc.GetMultiLineTextExtent(msg, &tWidth, &tHeight); - wxPoint dispos(m_curpos); + wxPoint dispos(m_curpos); - if (m_align & wxALIGN_CENTER_HORIZONTAL) { - dispos.x = (m_dc.GetSize().GetWidth() - tWidth) / 2; - } else if (m_align & wxALIGN_RIGHT) { - dispos.x = m_dc.GetSize().GetWidth() - tWidth; - } + if (m_align & wxALIGN_CENTER_HORIZONTAL) + { + dispos.x = (m_dc.GetSize().GetWidth() - tWidth) / 2; + } + else if (m_align & wxALIGN_RIGHT) + { + dispos.x = m_dc.GetSize().GetWidth() - tWidth; + } - m_dc.DrawText(msg, dispos); - m_curpos.y += tHeight + m_leading; + m_dc.DrawText(msg, dispos); + m_curpos.y += tHeight + m_leading; } // Splits incoming multi-line strings into pieces, and dispatches each line individually // to the text writer. -void pxWindowTextWriter::_DoWrite(const wxChar *msg) +void pxWindowTextWriter::_DoWrite(const wxChar* msg) { - pxAssert(msg); + pxAssert(msg); - wxArrayString parts; - SplitString(parts, msg, L'\n'); + wxArrayString parts; + SplitString(parts, msg, L'\n'); - for (size_t i = 0; i < parts.GetCount(); ++i) - _DoWriteLn(parts[i]); + for (size_t i = 0; i < parts.GetCount(); ++i) + _DoWriteLn(parts[i]); } -pxWindowTextWriter &pxWindowTextWriter::SetFont(const wxFont &font) +pxWindowTextWriter& pxWindowTextWriter::SetFont(const wxFont& font) { - m_dc.SetFont(font); - return *this; + m_dc.SetFont(font); + return *this; } -pxWindowTextWriter &pxWindowTextWriter::Align(const wxAlignment &align) +pxWindowTextWriter& pxWindowTextWriter::Align(const wxAlignment& align) { - m_align = align; - m_curpos.x = 0; - return *this; + m_align = align; + m_curpos.x = 0; + return *this; } -pxWindowTextWriter &pxWindowTextWriter::WriteLn() +pxWindowTextWriter& pxWindowTextWriter::WriteLn() { - _DoWriteLn(L""); - return *this; + _DoWriteLn(L""); + return *this; } -pxWindowTextWriter &pxWindowTextWriter::WriteLn(const wxChar *fmt) +pxWindowTextWriter& pxWindowTextWriter::WriteLn(const wxChar* fmt) { - _DoWrite(fmt); - return *this; + _DoWrite(fmt); + return *this; } -pxWindowTextWriter &pxWindowTextWriter::FormatLn(const wxChar *fmt, ...) +pxWindowTextWriter& pxWindowTextWriter::FormatLn(const wxChar* fmt, ...) { - va_list args; - va_start(args, fmt); - _DoWrite(pxsFmtV(fmt, args)); - va_end(args); - return *this; + va_list args; + va_start(args, fmt); + _DoWrite(pxsFmtV(fmt, args)); + va_end(args); + return *this; } -pxWindowTextWriter &pxWindowTextWriter::WriteLn(const wxString fmt) +pxWindowTextWriter& pxWindowTextWriter::WriteLn(const wxString fmt) { - _DoWrite(fmt.wc_str()); - return *this; + _DoWrite(fmt.wc_str()); + return *this; } diff --git a/common/wxAppWithHelpers.cpp b/common/wxAppWithHelpers.cpp index 01613f1112..5e72e36e3d 100644 --- a/common/wxAppWithHelpers.cpp +++ b/common/wxAppWithHelpers.cpp @@ -27,21 +27,21 @@ wxIMPLEMENT_DYNAMIC_CLASS(pxSimpleEvent, wxEvent); ConsoleLogSource_App::ConsoleLogSource_App() { - static const TraceLogDescriptor myDesc = - { - L"AppEvents", L"App Events", - pxLt("Includes idle event processing and some other uncommon event usages.")}; + static const TraceLogDescriptor myDesc = + { + L"AppEvents", L"App Events", + pxLt("Includes idle event processing and some other uncommon event usages.")}; - m_Descriptor = &myDesc; + m_Descriptor = &myDesc; } ConsoleLogSource_App pxConLog_App; void BaseDeletableObject::DoDeletion() { - wxAppWithHelpers *app = wxDynamicCast(wxApp::GetInstance(), wxAppWithHelpers); - pxAssert(app != NULL); - app->DeleteObject(*this); + wxAppWithHelpers* app = wxDynamicCast(wxApp::GetInstance(), wxAppWithHelpers); + pxAssert(app != NULL); + app->DeleteObject(*this); } @@ -49,64 +49,67 @@ void BaseDeletableObject::DoDeletion() // SynchronousActionState Implementations // -------------------------------------------------------------------------------------- -void SynchronousActionState::SetException(const BaseException &ex) +void SynchronousActionState::SetException(const BaseException& ex) { - m_exception = ScopedExcept(ex.Clone()); + m_exception = ScopedExcept(ex.Clone()); } -void SynchronousActionState::SetException(BaseException *ex) +void SynchronousActionState::SetException(BaseException* ex) { - if (!m_posted) { - m_exception = ScopedExcept(ex); - } else if (wxTheApp) { - // transport the exception to the main thread, since the message is fully - // asynchronous, or has already entered an asynchronous state. Message is sent - // as a non-blocking action since proper handling of user errors on async messages - // is *usually* to log/ignore it (hah), or to suspend emulation and issue a dialog - // box to the user. + if (!m_posted) + { + m_exception = ScopedExcept(ex); + } + else if (wxTheApp) + { + // transport the exception to the main thread, since the message is fully + // asynchronous, or has already entered an asynchronous state. Message is sent + // as a non-blocking action since proper handling of user errors on async messages + // is *usually* to log/ignore it (hah), or to suspend emulation and issue a dialog + // box to the user. - pxExceptionEvent ev(ex); - wxTheApp->AddPendingEvent(ev); - } + pxExceptionEvent ev(ex); + wxTheApp->AddPendingEvent(ev); + } } void SynchronousActionState::RethrowException() const { - if (m_exception) - m_exception->Rethrow(); + if (m_exception) + m_exception->Rethrow(); } int SynchronousActionState::WaitForResult() { - m_sema.WaitNoCancel(); - RethrowException(); - return return_value; + m_sema.WaitNoCancel(); + RethrowException(); + return return_value; } int SynchronousActionState::WaitForResult_NoExceptions() { - m_sema.WaitNoCancel(); - return return_value; + m_sema.WaitNoCancel(); + return return_value; } void SynchronousActionState::PostResult(int res) { - return_value = res; - PostResult(); + return_value = res; + PostResult(); } void SynchronousActionState::ClearResult() { - m_posted = false; - m_exception = NULL; + m_posted = false; + m_exception = NULL; } void SynchronousActionState::PostResult() { - if (m_posted) - return; - m_posted = true; - m_sema.Post(); + if (m_posted) + return; + m_posted = true; + m_sema.Post(); } // -------------------------------------------------------------------------------------- @@ -115,40 +118,41 @@ void SynchronousActionState::PostResult() wxIMPLEMENT_DYNAMIC_CLASS(pxActionEvent, wxEvent); -pxActionEvent::pxActionEvent(SynchronousActionState *sema, int msgtype) - : wxEvent(0, msgtype) +pxActionEvent::pxActionEvent(SynchronousActionState* sema, int msgtype) + : wxEvent(0, msgtype) { - m_state = sema; + m_state = sema; } -pxActionEvent::pxActionEvent(SynchronousActionState &sema, int msgtype) - : wxEvent(0, msgtype) +pxActionEvent::pxActionEvent(SynchronousActionState& sema, int msgtype) + : wxEvent(0, msgtype) { - m_state = &sema; + m_state = &sema; } -pxActionEvent::pxActionEvent(const pxActionEvent &src) - : wxEvent(src) +pxActionEvent::pxActionEvent(const pxActionEvent& src) + : wxEvent(src) { - m_state = src.m_state; + m_state = src.m_state; } -void pxActionEvent::SetException(const BaseException &ex) +void pxActionEvent::SetException(const BaseException& ex) { - SetException(ex.Clone()); + SetException(ex.Clone()); } -void pxActionEvent::SetException(BaseException *ex) +void pxActionEvent::SetException(BaseException* ex) { - const wxString &prefix(pxsFmt(L"(%s) ", GetClassInfo()->GetClassName())); - ex->DiagMsg() = prefix + ex->DiagMsg(); + const wxString& prefix(pxsFmt(L"(%s) ", GetClassInfo()->GetClassName())); + ex->DiagMsg() = prefix + ex->DiagMsg(); - if (!m_state) { - ScopedExcept exptr(ex); // auto-delete it after handling. - ex->Rethrow(); - } + if (!m_state) + { + ScopedExcept exptr(ex); // auto-delete it after handling. + ex->Rethrow(); + } - m_state->SetException(ex); + m_state->SetException(ex); } // -------------------------------------------------------------------------------------- @@ -156,58 +160,59 @@ void pxActionEvent::SetException(BaseException *ex) // -------------------------------------------------------------------------------------- wxIMPLEMENT_DYNAMIC_CLASS(pxSynchronousCommandEvent, wxCommandEvent); -pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState *sema, wxEventType commandType, int winid) - : wxCommandEvent(pxEvt_SynchronousCommand, winid) +pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState* sema, wxEventType commandType, int winid) + : wxCommandEvent(pxEvt_SynchronousCommand, winid) { - m_sync = sema; - m_realEvent = commandType; + m_sync = sema; + m_realEvent = commandType; } -pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState &sema, wxEventType commandType, int winid) - : wxCommandEvent(pxEvt_SynchronousCommand) +pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState& sema, wxEventType commandType, int winid) + : wxCommandEvent(pxEvt_SynchronousCommand) { - m_sync = &sema; - m_realEvent = commandType; + m_sync = &sema; + m_realEvent = commandType; } -pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState *sema, const wxCommandEvent &evt) - : wxCommandEvent(evt) +pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState* sema, const wxCommandEvent& evt) + : wxCommandEvent(evt) { - m_sync = sema; - m_realEvent = evt.GetEventType(); - SetEventType(pxEvt_SynchronousCommand); + m_sync = sema; + m_realEvent = evt.GetEventType(); + SetEventType(pxEvt_SynchronousCommand); } -pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState &sema, const wxCommandEvent &evt) - : wxCommandEvent(evt) +pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState& sema, const wxCommandEvent& evt) + : wxCommandEvent(evt) { - m_sync = &sema; - m_realEvent = evt.GetEventType(); - SetEventType(pxEvt_SynchronousCommand); + m_sync = &sema; + m_realEvent = evt.GetEventType(); + SetEventType(pxEvt_SynchronousCommand); } -pxSynchronousCommandEvent::pxSynchronousCommandEvent(const pxSynchronousCommandEvent &src) - : wxCommandEvent(src) +pxSynchronousCommandEvent::pxSynchronousCommandEvent(const pxSynchronousCommandEvent& src) + : wxCommandEvent(src) { - m_sync = src.m_sync; - m_realEvent = src.m_realEvent; + m_sync = src.m_sync; + m_realEvent = src.m_realEvent; } -void pxSynchronousCommandEvent::SetException(const BaseException &ex) +void pxSynchronousCommandEvent::SetException(const BaseException& ex) { - if (!m_sync) - ex.Rethrow(); - m_sync->SetException(ex); + if (!m_sync) + ex.Rethrow(); + m_sync->SetException(ex); } -void pxSynchronousCommandEvent::SetException(BaseException *ex) +void pxSynchronousCommandEvent::SetException(BaseException* ex) { - if (!m_sync) { - ScopedExcept exptr(ex); // auto-delete it after handling. - ex->Rethrow(); - } + if (!m_sync) + { + ScopedExcept exptr(ex); // auto-delete it after handling. + ex->Rethrow(); + } - m_sync->SetException(ex); + m_sync->SetException(ex); } // -------------------------------------------------------------------------------------- @@ -219,46 +224,46 @@ void pxSynchronousCommandEvent::SetException(BaseException *ex) // class pxRpcEvent : public pxActionEvent { - wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxRpcEvent); + wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxRpcEvent); - typedef pxActionEvent _parent; + typedef pxActionEvent _parent; protected: - void (*m_Method)(); + void (*m_Method)(); public: - virtual ~pxRpcEvent() = default; - virtual pxRpcEvent *Clone() const { return new pxRpcEvent(*this); } + virtual ~pxRpcEvent() = default; + virtual pxRpcEvent* Clone() const { return new pxRpcEvent(*this); } - explicit pxRpcEvent(void (*method)() = NULL, SynchronousActionState *sema = NULL) - : pxActionEvent(sema) - { - m_Method = method; - } + explicit pxRpcEvent(void (*method)() = NULL, SynchronousActionState* sema = NULL) + : pxActionEvent(sema) + { + m_Method = method; + } - explicit pxRpcEvent(void (*method)(), SynchronousActionState &sema) - : pxActionEvent(sema) - { - m_Method = method; - } + explicit pxRpcEvent(void (*method)(), SynchronousActionState& sema) + : pxActionEvent(sema) + { + m_Method = method; + } - pxRpcEvent(const pxRpcEvent &src) - : pxActionEvent(src) - { - m_Method = src.m_Method; - } + pxRpcEvent(const pxRpcEvent& src) + : pxActionEvent(src) + { + m_Method = src.m_Method; + } - void SetMethod(void (*method)()) - { - m_Method = method; - } + void SetMethod(void (*method)()) + { + m_Method = method; + } protected: - void InvokeEvent() - { - if (m_Method) - m_Method(); - } + void InvokeEvent() + { + if (m_Method) + m_Method(); + } }; wxIMPLEMENT_DYNAMIC_CLASS(pxRpcEvent, pxActionEvent); @@ -266,16 +271,16 @@ wxIMPLEMENT_DYNAMIC_CLASS(pxRpcEvent, pxActionEvent); // -------------------------------------------------------------------------------------- // pxExceptionEvent implementations // -------------------------------------------------------------------------------------- -pxExceptionEvent::pxExceptionEvent(const BaseException &ex) +pxExceptionEvent::pxExceptionEvent(const BaseException& ex) { - m_except = ex.Clone(); + m_except = ex.Clone(); } void pxExceptionEvent::InvokeEvent() { - ScopedExcept deleteMe(m_except); - if (deleteMe) - deleteMe->Rethrow(); + ScopedExcept deleteMe(m_except); + if (deleteMe) + deleteMe->Rethrow(); } // -------------------------------------------------------------------------------------- @@ -291,17 +296,17 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxAppWithHelpers, wxApp); // Posts a method to the main thread; non-blocking. Post occurs even when called from the // main thread. -void wxAppWithHelpers::PostMethod(FnType_Void *method) +void wxAppWithHelpers::PostMethod(FnType_Void* method) { - PostEvent(pxRpcEvent(method)); + PostEvent(pxRpcEvent(method)); } // Posts a method to the main thread; non-blocking. Post occurs even when called from the // main thread. -void wxAppWithHelpers::PostIdleMethod(FnType_Void *method) +void wxAppWithHelpers::PostIdleMethod(FnType_Void* method) { - pxRpcEvent evt(method); - AddIdleEvent(evt); + pxRpcEvent evt(method); + AddIdleEvent(evt); } // Invokes the specified void method, or posts the method to the main thread if the calling @@ -316,16 +321,16 @@ void wxAppWithHelpers::PostIdleMethod(FnType_Void *method) // TRUE if the method was invoked. // -bool wxAppWithHelpers::Rpc_TryInvoke(FnType_Void *method) +bool wxAppWithHelpers::Rpc_TryInvoke(FnType_Void* method) { - if (wxThread::IsMain()) - return false; + if (wxThread::IsMain()) + return false; - SynchronousActionState sync; - PostEvent(pxRpcEvent(method, sync)); - sync.WaitForResult(); + SynchronousActionState sync; + PostEvent(pxRpcEvent(method, sync)); + sync.WaitForResult(); - return true; + return true; } // Invokes the specified void method, or posts the method to the main thread if the calling @@ -339,93 +344,98 @@ bool wxAppWithHelpers::Rpc_TryInvoke(FnType_Void *method) // FALSE if the method was not posted to the main thread (meaning this IS the main thread!) // TRUE if the method was posted. // -bool wxAppWithHelpers::Rpc_TryInvokeAsync(FnType_Void *method) +bool wxAppWithHelpers::Rpc_TryInvokeAsync(FnType_Void* method) { - if (wxThread::IsMain()) - return false; - PostEvent(pxRpcEvent(method)); - return true; + if (wxThread::IsMain()) + return false; + PostEvent(pxRpcEvent(method)); + return true; } -void wxAppWithHelpers::ProcessMethod(FnType_Void *method) +void wxAppWithHelpers::ProcessMethod(FnType_Void* method) { - if (wxThread::IsMain()) { - method(); - return; - } + if (wxThread::IsMain()) + { + method(); + return; + } - SynchronousActionState sync; - PostEvent(pxRpcEvent(method, sync)); - sync.WaitForResult(); + SynchronousActionState sync; + PostEvent(pxRpcEvent(method, sync)); + sync.WaitForResult(); } -void wxAppWithHelpers::PostEvent(const wxEvent &evt) +void wxAppWithHelpers::PostEvent(const wxEvent& evt) { - // Const Cast is OK! - // Truth is, AddPendingEvent should be a const-qualified parameter, as - // it makes an immediate clone copy of the event -- but wxWidgets - // fails again in structured C/C++ design design. So I'm forcing it as such - // here. -- air + // Const Cast is OK! + // Truth is, AddPendingEvent should be a const-qualified parameter, as + // it makes an immediate clone copy of the event -- but wxWidgets + // fails again in structured C/C++ design design. So I'm forcing it as such + // here. -- air - _parent::AddPendingEvent(const_cast(evt)); + _parent::AddPendingEvent(const_cast(evt)); } -bool wxAppWithHelpers::ProcessEvent(wxEvent &evt) +bool wxAppWithHelpers::ProcessEvent(wxEvent& evt) { - // Note: We can't do an automatic blocking post of the message here, because wxWidgets - // isn't really designed for it (some events return data to the caller via the event - // struct, and posting the event would require a temporary clone, where changes would - // be lost). + // Note: We can't do an automatic blocking post of the message here, because wxWidgets + // isn't really designed for it (some events return data to the caller via the event + // struct, and posting the event would require a temporary clone, where changes would + // be lost). - AffinityAssert_AllowFrom_MainUI(); - return _parent::ProcessEvent(evt); + AffinityAssert_AllowFrom_MainUI(); + return _parent::ProcessEvent(evt); } -bool wxAppWithHelpers::ProcessEvent(wxEvent *evt) +bool wxAppWithHelpers::ProcessEvent(wxEvent* evt) { - AffinityAssert_AllowFrom_MainUI(); - std::unique_ptr deleteMe(evt); - return _parent::ProcessEvent(*deleteMe); + AffinityAssert_AllowFrom_MainUI(); + std::unique_ptr deleteMe(evt); + return _parent::ProcessEvent(*deleteMe); } -bool wxAppWithHelpers::ProcessEvent(pxActionEvent &evt) +bool wxAppWithHelpers::ProcessEvent(pxActionEvent& evt) { - if (wxThread::IsMain()) - return _parent::ProcessEvent(evt); - else { - SynchronousActionState sync; - evt.SetSyncState(sync); - AddPendingEvent(evt); - sync.WaitForResult(); - return true; - } + if (wxThread::IsMain()) + return _parent::ProcessEvent(evt); + else + { + SynchronousActionState sync; + evt.SetSyncState(sync); + AddPendingEvent(evt); + sync.WaitForResult(); + return true; + } } -bool wxAppWithHelpers::ProcessEvent(pxActionEvent *evt) +bool wxAppWithHelpers::ProcessEvent(pxActionEvent* evt) { - if (wxThread::IsMain()) { - std::unique_ptr deleteMe(evt); - return _parent::ProcessEvent(*deleteMe); - } else { - SynchronousActionState sync; - evt->SetSyncState(sync); - AddPendingEvent(*evt); - sync.WaitForResult(); - return true; - } + if (wxThread::IsMain()) + { + std::unique_ptr deleteMe(evt); + return _parent::ProcessEvent(*deleteMe); + } + else + { + SynchronousActionState sync; + evt->SetSyncState(sync); + AddPendingEvent(*evt); + sync.WaitForResult(); + return true; + } } void wxAppWithHelpers::CleanUp() { - // I'm pretty sure the message pump is dead by now, which means we need to run through - // idle event list by hand and process the pending Deletion messages (all others can be - // ignored -- it's only deletions we want handled, and really we *could* ignore those too - // but I like to be tidy. -- air + // I'm pretty sure the message pump is dead by now, which means we need to run through + // idle event list by hand and process the pending Deletion messages (all others can be + // ignored -- it's only deletions we want handled, and really we *could* ignore those too + // but I like to be tidy. -- air - //IdleEventDispatcher( "CleanUp" ); - //DeletionDispatcher(); - _parent::CleanUp(); + //IdleEventDispatcher( "CleanUp" ); + //DeletionDispatcher(); + _parent::CleanUp(); } // Executes the event with exception handling. If the event throws an exception, the exception @@ -434,211 +444,227 @@ void wxAppWithHelpers::CleanUp() // should overload InvokeEvent() instead. void pxActionEvent::_DoInvokeEvent() { - AffinityAssert_AllowFrom_MainUI(); + AffinityAssert_AllowFrom_MainUI(); - try { - InvokeEvent(); - } catch (BaseException &ex) { - SetException(ex); - } catch (std::runtime_error &ex) { - SetException(new Exception::RuntimeError(ex)); - } + try + { + InvokeEvent(); + } + catch (BaseException& ex) + { + SetException(ex); + } + catch (std::runtime_error& ex) + { + SetException(new Exception::RuntimeError(ex)); + } - if (m_state) - m_state->PostResult(); + if (m_state) + m_state->PostResult(); } -void wxAppWithHelpers::OnSynchronousCommand(pxSynchronousCommandEvent &evt) +void wxAppWithHelpers::OnSynchronousCommand(pxSynchronousCommandEvent& evt) { - AffinityAssert_AllowFrom_MainUI(); + AffinityAssert_AllowFrom_MainUI(); - pxAppLog.Write(L"(App) Executing command event synchronously..."); - evt.SetEventType(evt.GetRealEventType()); + pxAppLog.Write(L"(App) Executing command event synchronously..."); + evt.SetEventType(evt.GetRealEventType()); - try { - ProcessEvent(evt); - } catch (BaseException &ex) { - evt.SetException(ex); - } catch (std::runtime_error &ex) { - evt.SetException(new Exception::RuntimeError(ex, evt.GetClassInfo()->GetClassName())); - } + try + { + ProcessEvent(evt); + } + catch (BaseException& ex) + { + evt.SetException(ex); + } + catch (std::runtime_error& ex) + { + evt.SetException(new Exception::RuntimeError(ex, evt.GetClassInfo()->GetClassName())); + } - if (Semaphore *sema = evt.GetSemaphore()) - sema->Post(); + if (Semaphore* sema = evt.GetSemaphore()) + sema->Post(); } -void wxAppWithHelpers::AddIdleEvent(const wxEvent &evt) +void wxAppWithHelpers::AddIdleEvent(const wxEvent& evt) { - ScopedLock lock(m_IdleEventMutex); - if (m_IdleEventQueue.empty()) - PostEvent(wxCommandEvent(pxEvt_StartIdleEventTimer)); + ScopedLock lock(m_IdleEventMutex); + if (m_IdleEventQueue.empty()) + PostEvent(wxCommandEvent(pxEvt_StartIdleEventTimer)); - m_IdleEventQueue.push_back(evt.Clone()); + m_IdleEventQueue.push_back(evt.Clone()); } -void wxAppWithHelpers::OnStartIdleEventTimer(wxCommandEvent &evt) +void wxAppWithHelpers::OnStartIdleEventTimer(wxCommandEvent& evt) { - ScopedLock lock(m_IdleEventMutex); - if (!m_IdleEventQueue.empty()) - m_IdleEventTimer.Start(100, true); + ScopedLock lock(m_IdleEventMutex); + if (!m_IdleEventQueue.empty()) + m_IdleEventTimer.Start(100, true); } -void wxAppWithHelpers::IdleEventDispatcher(const wxChar *action) +void wxAppWithHelpers::IdleEventDispatcher(const wxChar* action) { - // Recursion is possible thanks to modal dialogs being issued from the idle event handler. - // (recursion shouldn't hurt anything anyway, since the node system re-creates the iterator - // on each pass) + // Recursion is possible thanks to modal dialogs being issued from the idle event handler. + // (recursion shouldn't hurt anything anyway, since the node system re-creates the iterator + // on each pass) - //static int __guard=0; - //RecursionGuard guard(__guard); - //if( !pxAssertDev(!guard.IsReentrant(), "Re-entrant call to IdleEventdispatcher caught on camera!") ) return; + //static int __guard=0; + //RecursionGuard guard(__guard); + //if( !pxAssertDev(!guard.IsReentrant(), "Re-entrant call to IdleEventdispatcher caught on camera!") ) return; - wxEventList postponed; - wxEventList::iterator node; + wxEventList postponed; + wxEventList::iterator node; - ScopedLock lock(m_IdleEventMutex); + ScopedLock lock(m_IdleEventMutex); - while (node = m_IdleEventQueue.begin(), node != m_IdleEventQueue.end()) { - std::unique_ptr deleteMe(*node); - m_IdleEventQueue.erase(node); + while (node = m_IdleEventQueue.begin(), node != m_IdleEventQueue.end()) + { + std::unique_ptr deleteMe(*node); + m_IdleEventQueue.erase(node); - lock.Release(); - if (!Threading::AllowDeletions() && (deleteMe->GetEventType() == pxEvt_DeleteThread)) { - // Threads that have active semaphores or mutexes (other threads are waiting on them) cannot - // be deleted because those mutex/sema objects will become invalid and cause the pending - // thread to crash. So we disallow deletions when those waits are in action, and continue - // to postpone the deletion of the thread until such time that it is safe. + lock.Release(); + if (!Threading::AllowDeletions() && (deleteMe->GetEventType() == pxEvt_DeleteThread)) + { + // Threads that have active semaphores or mutexes (other threads are waiting on them) cannot + // be deleted because those mutex/sema objects will become invalid and cause the pending + // thread to crash. So we disallow deletions when those waits are in action, and continue + // to postpone the deletion of the thread until such time that it is safe. - pxThreadLog.Write(((pxThread *)((wxCommandEvent *)deleteMe.get())->GetClientData())->GetName(), L"Deletion postponed due to mutex or semaphore dependency."); - postponed.push_back(deleteMe.release()); - } else { - pxAppLog.Write(L"(AppIdleQueue%s) Dispatching event '%s'", action, deleteMe->GetClassInfo()->GetClassName()); - ProcessEvent(*deleteMe); // dereference to prevent auto-deletion by ProcessEvent - } - lock.Acquire(); - } + pxThreadLog.Write(((pxThread*)((wxCommandEvent*)deleteMe.get())->GetClientData())->GetName(), L"Deletion postponed due to mutex or semaphore dependency."); + postponed.push_back(deleteMe.release()); + } + else + { + pxAppLog.Write(L"(AppIdleQueue%s) Dispatching event '%s'", action, deleteMe->GetClassInfo()->GetClassName()); + ProcessEvent(*deleteMe); // dereference to prevent auto-deletion by ProcessEvent + } + lock.Acquire(); + } - m_IdleEventQueue = postponed; - if (!m_IdleEventQueue.empty()) - pxAppLog.Write(L"(AppIdleQueue%s) %d events postponed due to dependencies.", action, m_IdleEventQueue.size()); + m_IdleEventQueue = postponed; + if (!m_IdleEventQueue.empty()) + pxAppLog.Write(L"(AppIdleQueue%s) %d events postponed due to dependencies.", action, m_IdleEventQueue.size()); } -void wxAppWithHelpers::OnIdleEvent(wxIdleEvent &evt) +void wxAppWithHelpers::OnIdleEvent(wxIdleEvent& evt) { - m_IdleEventTimer.Stop(); - IdleEventDispatcher(); + m_IdleEventTimer.Stop(); + IdleEventDispatcher(); } -void wxAppWithHelpers::OnIdleEventTimeout(wxTimerEvent &evt) +void wxAppWithHelpers::OnIdleEventTimeout(wxTimerEvent& evt) { - IdleEventDispatcher(L"[Timeout]"); + IdleEventDispatcher(L"[Timeout]"); } void wxAppWithHelpers::Ping() { - pxThreadLog.Write(pxGetCurrentThreadName().c_str(), L"App Event Ping Requested."); + pxThreadLog.Write(pxGetCurrentThreadName().c_str(), L"App Event Ping Requested."); - SynchronousActionState sync; - pxActionEvent evt(sync); - AddIdleEvent(evt); - sync.WaitForResult(); + SynchronousActionState sync; + pxActionEvent evt(sync); + AddIdleEvent(evt); + sync.WaitForResult(); } -void wxAppWithHelpers::PostCommand(void *clientData, int evtType, int intParam, long longParam, const wxString &stringParam) +void wxAppWithHelpers::PostCommand(void* clientData, int evtType, int intParam, long longParam, const wxString& stringParam) { - wxCommandEvent evt(evtType); - evt.SetClientData(clientData); - evt.SetInt(intParam); - evt.SetExtraLong(longParam); - evt.SetString(stringParam); - AddPendingEvent(evt); + wxCommandEvent evt(evtType); + evt.SetClientData(clientData); + evt.SetInt(intParam); + evt.SetExtraLong(longParam); + evt.SetString(stringParam); + AddPendingEvent(evt); } -void wxAppWithHelpers::PostCommand(int evtType, int intParam, long longParam, const wxString &stringParam) +void wxAppWithHelpers::PostCommand(int evtType, int intParam, long longParam, const wxString& stringParam) { - PostCommand(NULL, evtType, intParam, longParam, stringParam); + PostCommand(NULL, evtType, intParam, longParam, stringParam); } -sptr wxAppWithHelpers::ProcessCommand(void *clientData, int evtType, int intParam, long longParam, const wxString &stringParam) +sptr wxAppWithHelpers::ProcessCommand(void* clientData, int evtType, int intParam, long longParam, const wxString& stringParam) { - SynchronousActionState sync; - pxSynchronousCommandEvent evt(sync, evtType); + SynchronousActionState sync; + pxSynchronousCommandEvent evt(sync, evtType); - evt.SetClientData(clientData); - evt.SetInt(intParam); - evt.SetExtraLong(longParam); - evt.SetString(stringParam); - AddPendingEvent(evt); - sync.WaitForResult(); + evt.SetClientData(clientData); + evt.SetInt(intParam); + evt.SetExtraLong(longParam); + evt.SetString(stringParam); + AddPendingEvent(evt); + sync.WaitForResult(); - return sync.return_value; + return sync.return_value; } -sptr wxAppWithHelpers::ProcessCommand(int evtType, int intParam, long longParam, const wxString &stringParam) +sptr wxAppWithHelpers::ProcessCommand(int evtType, int intParam, long longParam, const wxString& stringParam) { - return ProcessCommand(NULL, evtType, intParam, longParam, stringParam); + return ProcessCommand(NULL, evtType, intParam, longParam, stringParam); } -void wxAppWithHelpers::PostAction(const pxActionEvent &evt) +void wxAppWithHelpers::PostAction(const pxActionEvent& evt) { - PostEvent(evt); + PostEvent(evt); } -void wxAppWithHelpers::ProcessAction(pxActionEvent &evt) +void wxAppWithHelpers::ProcessAction(pxActionEvent& evt) { - if (!wxThread::IsMain()) { - SynchronousActionState sync; - evt.SetSyncState(sync); - AddPendingEvent(evt); - sync.WaitForResult(); - } else - evt._DoInvokeEvent(); + if (!wxThread::IsMain()) + { + SynchronousActionState sync; + evt.SetSyncState(sync); + AddPendingEvent(evt); + sync.WaitForResult(); + } + else + evt._DoInvokeEvent(); } -void wxAppWithHelpers::DeleteObject(BaseDeletableObject &obj) +void wxAppWithHelpers::DeleteObject(BaseDeletableObject& obj) { - pxAssert(!obj.IsBeingDeleted()); - wxCommandEvent evt(pxEvt_DeleteObject); - evt.SetClientData((void *)&obj); - AddIdleEvent(evt); + pxAssert(!obj.IsBeingDeleted()); + wxCommandEvent evt(pxEvt_DeleteObject); + evt.SetClientData((void*)&obj); + AddIdleEvent(evt); } -void wxAppWithHelpers::DeleteThread(pxThread &obj) +void wxAppWithHelpers::DeleteThread(pxThread& obj) { - pxThreadLog.Write(obj.GetName(), L"Scheduling for deletion..."); - wxCommandEvent evt(pxEvt_DeleteThread); - evt.SetClientData((void *)&obj); - AddIdleEvent(evt); + pxThreadLog.Write(obj.GetName(), L"Scheduling for deletion..."); + wxCommandEvent evt(pxEvt_DeleteThread); + evt.SetClientData((void*)&obj); + AddIdleEvent(evt); } bool wxAppWithHelpers::OnInit() { - Bind(pxEvt_SynchronousCommand, &wxAppWithHelpers::OnSynchronousCommand, this); - Bind(pxEvt_InvokeAction, &wxAppWithHelpers::OnInvokeAction, this); + Bind(pxEvt_SynchronousCommand, &wxAppWithHelpers::OnSynchronousCommand, this); + Bind(pxEvt_InvokeAction, &wxAppWithHelpers::OnInvokeAction, this); - Bind(pxEvt_StartIdleEventTimer, &wxAppWithHelpers::OnStartIdleEventTimer, this); + Bind(pxEvt_StartIdleEventTimer, &wxAppWithHelpers::OnStartIdleEventTimer, this); - Bind(pxEvt_DeleteObject, &wxAppWithHelpers::OnDeleteObject, this); - Bind(pxEvt_DeleteThread, &wxAppWithHelpers::OnDeleteThread, this); + Bind(pxEvt_DeleteObject, &wxAppWithHelpers::OnDeleteObject, this); + Bind(pxEvt_DeleteThread, &wxAppWithHelpers::OnDeleteThread, this); - Bind(wxEVT_IDLE, &wxAppWithHelpers::OnIdleEvent, this); + Bind(wxEVT_IDLE, &wxAppWithHelpers::OnIdleEvent, this); - Bind(wxEVT_TIMER, &wxAppWithHelpers::OnIdleEventTimeout, this, m_IdleEventTimer.GetId()); + Bind(wxEVT_TIMER, &wxAppWithHelpers::OnIdleEventTimeout, this, m_IdleEventTimer.GetId()); - return _parent::OnInit(); + return _parent::OnInit(); } -void wxAppWithHelpers::OnInvokeAction(pxActionEvent &evt) +void wxAppWithHelpers::OnInvokeAction(pxActionEvent& evt) { - evt._DoInvokeEvent(); // wow this is easy! + evt._DoInvokeEvent(); // wow this is easy! } -void wxAppWithHelpers::OnDeleteObject(wxCommandEvent &evt) +void wxAppWithHelpers::OnDeleteObject(wxCommandEvent& evt) { - if (evt.GetClientData() == NULL) - return; - delete (BaseDeletableObject *)evt.GetClientData(); + if (evt.GetClientData() == NULL) + return; + delete (BaseDeletableObject*)evt.GetClientData(); } // In theory we create a Pcsx2App object which inherit from wxAppWithHelpers, @@ -648,35 +674,36 @@ void wxAppWithHelpers::OnDeleteObject(wxCommandEvent &evt) // be called first. This constructor will build some wx objects (here wxTimer) // that require a trait. In others word, wxAppWithHelpers::CreateTraits will be // called instead -wxAppTraits *wxAppWithHelpers::CreateTraits() +wxAppTraits* wxAppWithHelpers::CreateTraits() { - return new Pcsx2AppTraits; + return new Pcsx2AppTraits; } // Threads have their own deletion handler that propagates exceptions thrown by the thread to the UI. // (thus we have a fairly automatic threaded exception system!) -void wxAppWithHelpers::OnDeleteThread(wxCommandEvent &evt) +void wxAppWithHelpers::OnDeleteThread(wxCommandEvent& evt) { - std::unique_ptr thr((pxThread *)evt.GetClientData()); - if (!thr) { - pxThreadLog.Write(L"null", L"OnDeleteThread: NULL thread object received (and ignored)."); - return; - } + std::unique_ptr thr((pxThread*)evt.GetClientData()); + if (!thr) + { + pxThreadLog.Write(L"null", L"OnDeleteThread: NULL thread object received (and ignored)."); + return; + } - pxThreadLog.Write(thr->GetName(), wxString(wxString(L"Thread object deleted successfully") + (thr->HasPendingException() ? L" [exception pending!]" : L"")).wc_str()); - thr->RethrowException(); + pxThreadLog.Write(thr->GetName(), wxString(wxString(L"Thread object deleted successfully") + (thr->HasPendingException() ? L" [exception pending!]" : L"")).wc_str()); + thr->RethrowException(); } wxAppWithHelpers::wxAppWithHelpers() - : m_IdleEventTimer(this) + : m_IdleEventTimer(this) { #ifdef __WXMSW__ - // This variable assignment ensures that MSVC links in the TLS setup stubs even in - // full optimization builds. Without it, DLLs that use TLS won't work because the - // FS segment register won't have been initialized by the main exe, due to tls_insurance - // being optimized away >_< --air + // This variable assignment ensures that MSVC links in the TLS setup stubs even in + // full optimization builds. Without it, DLLs that use TLS won't work because the + // FS segment register won't have been initialized by the main exe, due to tls_insurance + // being optimized away >_< --air - static thread_local int tls_insurance = 0; - tls_insurance = 1; + static thread_local int tls_insurance = 0; + tls_insurance = 1; #endif } diff --git a/common/wxAppWithHelpers.h b/common/wxAppWithHelpers.h index f9555cdd24..7537d341a3 100644 --- a/common/wxAppWithHelpers.h +++ b/common/wxAppWithHelpers.h @@ -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,97 +49,97 @@ extern ConsoleLogSource_App pxConLog_App; class ModalButtonPanel : public wxPanelWithHelpers { public: - ModalButtonPanel(wxWindow *window, const MsgButtons &buttons); - virtual ~ModalButtonPanel() = default; + ModalButtonPanel(wxWindow* window, const MsgButtons& buttons); + virtual ~ModalButtonPanel() = default; - 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 wxEventList; +typedef std::list wxEventList; // -------------------------------------------------------------------------------------- // wxAppWithHelpers // -------------------------------------------------------------------------------------- class wxAppWithHelpers : public wxApp { - typedef wxApp _parent; + typedef wxApp _parent; - wxDECLARE_DYNAMIC_CLASS(wxAppWithHelpers); + wxDECLARE_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 CleanUp(); - void DeleteObject(BaseDeletableObject &obj); - void DeleteObject(BaseDeletableObject *obj) - { - if (obj == NULL) - return; - DeleteObject(*obj); - } + void DeleteObject(BaseDeletableObject& obj); + void DeleteObject(BaseDeletableObject* obj) + { + if (obj == NULL) + return; + DeleteObject(*obj); + } - void DeleteThread(Threading::pxThread &obj); - void DeleteThread(Threading::pxThread *obj) - { - if (obj == NULL) - return; - DeleteThread(*obj); - } + void DeleteThread(Threading::pxThread& obj); + void DeleteThread(Threading::pxThread* obj) + { + if (obj == NULL) + return; + DeleteThread(*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 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); - bool Rpc_TryInvoke(FnType_Void *method); - bool Rpc_TryInvokeAsync(FnType_Void *method); + bool Rpc_TryInvoke(FnType_Void* method); + bool Rpc_TryInvokeAsync(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); + 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 ProcessAction(pxActionEvent &evt); - void PostAction(const pxActionEvent &evt); + void ProcessAction(pxActionEvent& evt); + void PostAction(const pxActionEvent& evt); - void Ping(); - bool OnInit(); - //int OnExit(); + void Ping(); + bool OnInit(); + //int OnExit(); - void AddIdleEvent(const wxEvent &evt); + void AddIdleEvent(const wxEvent& evt); - void PostEvent(const wxEvent &evt); - bool ProcessEvent(wxEvent &evt); - bool ProcessEvent(wxEvent *evt); + void PostEvent(const wxEvent& evt); + bool ProcessEvent(wxEvent& evt); + bool ProcessEvent(wxEvent* evt); - bool ProcessEvent(pxActionEvent &evt); - bool ProcessEvent(pxActionEvent *evt); + bool ProcessEvent(pxActionEvent& evt); + bool ProcessEvent(pxActionEvent* evt); protected: - void IdleEventDispatcher(const wxChar *action = wxEmptyString); + 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 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); +} // namespace Msgbox diff --git a/common/wxBaseTools.h b/common/wxBaseTools.h index 748db15946..c55861d9a2 100644 --- a/common/wxBaseTools.h +++ b/common/wxBaseTools.h @@ -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,28 +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() - { - wxLog::EnableLogging(m_prev); - } + virtual ~wxDoNotLogInThisScope() + { + 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); diff --git a/common/wxGuiTools.cpp b/common/wxGuiTools.cpp index 74a9d73490..a5f6a2c283 100644 --- a/common/wxGuiTools.cpp +++ b/common/wxGuiTools.cpp @@ -22,171 +22,173 @@ #include const pxAlignmentType - pxCentre = {pxAlignmentType::Center}, // Horizontal centered alignment - pxCenter = pxCentre, - pxMiddle = {pxAlignmentType::Middle}, // vertical centered alignment + pxCentre = {pxAlignmentType::Center}, // Horizontal centered alignment + pxCenter = pxCentre, + pxMiddle = {pxAlignmentType::Middle}, // vertical centered alignment - pxAlignLeft = {pxAlignmentType::Left}, - pxAlignRight = {pxAlignmentType::Right}, - pxAlignTop = {pxAlignmentType::Top}, - pxAlignBottom = {pxAlignmentType::Bottom}; + pxAlignLeft = {pxAlignmentType::Left}, + pxAlignRight = {pxAlignmentType::Right}, + pxAlignTop = {pxAlignmentType::Top}, + pxAlignBottom = {pxAlignmentType::Bottom}; const pxStretchType - pxShrink = {pxStretchType::Shrink}, - pxExpand = {pxStretchType::Expand}, - pxShaped = {pxStretchType::Shaped}, - pxReserveHidden = {pxStretchType::ReserveHidden}, - pxFixedMinimum = {pxStretchType::FixedMinimum}; + pxShrink = {pxStretchType::Shrink}, + pxExpand = {pxStretchType::Expand}, + pxShaped = {pxStretchType::Shaped}, + pxReserveHidden = {pxStretchType::ReserveHidden}, + pxFixedMinimum = {pxStretchType::FixedMinimum}; wxSizerFlags pxAlignmentType::Apply(wxSizerFlags flags) const { - switch (intval) { - case Centre: - flags.Align(flags.GetFlags() | wxALIGN_CENTRE_HORIZONTAL); - break; + switch (intval) + { + case Centre: + flags.Align(flags.GetFlags() | wxALIGN_CENTRE_HORIZONTAL); + break; - case Middle: - flags.Align(flags.GetFlags() | wxALIGN_CENTRE_VERTICAL); - break; + case Middle: + flags.Align(flags.GetFlags() | wxALIGN_CENTRE_VERTICAL); + break; - case Left: - flags.Left(); - break; + case Left: + flags.Left(); + break; - case Right: - flags.Right(); - break; + case Right: + flags.Right(); + break; - case Top: - flags.Top(); - break; + case Top: + flags.Top(); + break; - case Bottom: - flags.Bottom(); - break; - } - return flags; + case Bottom: + flags.Bottom(); + break; + } + return flags; } wxSizerFlags pxStretchType::Apply(wxSizerFlags flags) const { - switch (intval) { - case Shrink: - //pxFail( "wxSHRINK is an ignored stretch flag." ); - break; + switch (intval) + { + case Shrink: + //pxFail( "wxSHRINK is an ignored stretch flag." ); + break; - case Expand: - flags.Expand(); - break; + case Expand: + flags.Expand(); + break; - case Shaped: - flags.Shaped(); - break; + case Shaped: + flags.Shaped(); + break; - case ReserveHidden: - flags.ReserveSpaceEvenIfHidden(); - break; + case ReserveHidden: + flags.ReserveSpaceEvenIfHidden(); + break; - case FixedMinimum: - flags.FixedMinSize(); - break; + case FixedMinimum: + flags.FixedMinSize(); + break; - //case Tile: - // pxAssert( "pxTile is an unsupported stretch tag (ignored)." ); - //break; - } - return flags; + //case Tile: + // pxAssert( "pxTile is an unsupported stretch tag (ignored)." ); + //break; + } + return flags; } -wxSizerFlags operator&(const wxSizerFlags &_flgs, const wxSizerFlags &_flgs2) +wxSizerFlags operator&(const wxSizerFlags& _flgs, const wxSizerFlags& _flgs2) { - //return align.Apply( _flgs ); - wxSizerFlags retval; + //return align.Apply( _flgs ); + wxSizerFlags retval; - uint allflags = (_flgs.GetFlags() | _flgs2.GetFlags()); + uint allflags = (_flgs.GetFlags() | _flgs2.GetFlags()); - retval.Align(allflags & wxALIGN_MASK); - if (allflags & wxEXPAND) - retval.Expand(); - if (allflags & wxSHAPED) - retval.Shaped(); - if (allflags & wxFIXED_MINSIZE) - retval.FixedMinSize(); - if (allflags & wxRESERVE_SPACE_EVEN_IF_HIDDEN) - retval.ReserveSpaceEvenIfHidden(); + retval.Align(allflags & wxALIGN_MASK); + if (allflags & wxEXPAND) + retval.Expand(); + if (allflags & wxSHAPED) + retval.Shaped(); + if (allflags & wxFIXED_MINSIZE) + retval.FixedMinSize(); + if (allflags & wxRESERVE_SPACE_EVEN_IF_HIDDEN) + retval.ReserveSpaceEvenIfHidden(); - // Compounding borders is probably a fair approach: - retval.Border(allflags & wxALL, _flgs.GetBorderInPixels() + _flgs2.GetBorderInPixels()); + // Compounding borders is probably a fair approach: + retval.Border(allflags & wxALL, _flgs.GetBorderInPixels() + _flgs2.GetBorderInPixels()); - // Compounding proportions works as well, I figure. - retval.Proportion(_flgs.GetProportion() + _flgs2.GetProportion()); + // Compounding proportions works as well, I figure. + retval.Proportion(_flgs.GetProportion() + _flgs2.GetProportion()); - return retval; + return retval; } // ---------------------------------------------------------------------------- // Reference/Handle versions! -void operator+=(wxSizer &target, wxWindow *src) +void operator+=(wxSizer& target, wxWindow* src) { - target.Add(src); + target.Add(src); } -void operator+=(wxSizer &target, wxSizer *src) +void operator+=(wxSizer& target, wxSizer* src) { - target.Add(src); + target.Add(src); } -void operator+=(wxSizer &target, wxWindow &src) +void operator+=(wxSizer& target, wxWindow& src) { - target.Add(&src); + target.Add(&src); } -void operator+=(wxSizer &target, wxSizer &src) +void operator+=(wxSizer& target, wxSizer& src) { - target.Add(&src); + target.Add(&src); } -void operator+=(wxSizer &target, int spacer) +void operator+=(wxSizer& target, int spacer) { - target.AddSpacer(spacer); + target.AddSpacer(spacer); } -void operator+=(wxSizer &target, const pxStretchSpacer &spacer) +void operator+=(wxSizer& target, const pxStretchSpacer& spacer) { - target.AddStretchSpacer(spacer.proportion); + target.AddStretchSpacer(spacer.proportion); } -void operator+=(wxWindow &target, int spacer) +void operator+=(wxWindow& target, int spacer) { - if (!pxAssert(target.GetSizer() != NULL)) - return; - target.GetSizer()->AddSpacer(spacer); + if (!pxAssert(target.GetSizer() != NULL)) + return; + target.GetSizer()->AddSpacer(spacer); } -void operator+=(wxWindow &target, const pxStretchSpacer &spacer) +void operator+=(wxWindow& target, const pxStretchSpacer& spacer) { - if (!pxAssert(target.GetSizer() != NULL)) - return; - target.GetSizer()->AddStretchSpacer(spacer.proportion); + if (!pxAssert(target.GetSizer() != NULL)) + return; + target.GetSizer()->AddStretchSpacer(spacer.proportion); } // ---------------------------------------------------------------------------- // Pointer versions! (note that C++ requires one of the two operator params be a // "poper" object type (non-pointer), so that's why there's only a couple of these. -void operator+=(wxSizer *target, wxWindow &src) +void operator+=(wxSizer* target, wxWindow& src) { - if (!pxAssert(target != NULL)) - return; - target->Add(&src); + if (!pxAssert(target != NULL)) + return; + target->Add(&src); } -void operator+=(wxSizer *target, wxSizer &src) +void operator+=(wxSizer* target, wxSizer& src) { - if (!pxAssert(target != NULL)) - return; - target->Add(&src); + if (!pxAssert(target != NULL)) + return; + target->Add(&src); } // ---------------------------------------------------------------------------- @@ -194,23 +196,23 @@ void operator+=(wxSizer *target, wxSizer &src) // Returns FALSE if the window position is considered invalid, which means that it's title // bar is most likely not easily grabble. Such a window should be moved to a valid or // default position. -bool pxIsValidWindowPosition(const wxWindow &window, const wxPoint &windowPos) +bool pxIsValidWindowPosition(const wxWindow& window, const wxPoint& windowPos) { - // The height of the window is only revlevant to the height of a title bar, which is - // all we need visible for the user to be able to drag the window into view. But - // there's no way to get that info from wx, so we'll just have to guesstimate... + // The height of the window is only revlevant to the height of a title bar, which is + // all we need visible for the user to be able to drag the window into view. But + // there's no way to get that info from wx, so we'll just have to guesstimate... - const wxSize sizeMatters(window.GetSize().GetWidth(), 32); + const wxSize sizeMatters(window.GetSize().GetWidth(), 32); - for (unsigned int i = 0; i < wxDisplay::GetCount(); i++) - { - const auto rect = wxDisplay(i).GetGeometry(); + for (unsigned int i = 0; i < wxDisplay::GetCount(); i++) + { + const auto rect = wxDisplay(i).GetGeometry(); - if (rect.Contains(wxRect(windowPos, sizeMatters))) - return true; - } + if (rect.Contains(wxRect(windowPos, sizeMatters))) + return true; + } - return false; + return false; } // Retrieves the area of the screen, which can be used to enforce a valid zone for @@ -218,7 +220,7 @@ bool pxIsValidWindowPosition(const wxWindow &window, const wxPoint &windowPos) // is the resolution of the desktop). wxRect wxGetDisplayArea() { - return wxRect(wxPoint(), wxGetDisplaySize()); + return wxRect(wxPoint(), wxGetDisplaySize()); } // -------------------------------------------------------------------------------------- @@ -234,17 +236,17 @@ wxRect wxGetDisplayArea() // wxSizerFlags pxSizerFlags::StdSpace() { - return wxSizerFlags().Border(wxALL, StdPadding); + return wxSizerFlags().Border(wxALL, StdPadding); } wxSizerFlags pxSizerFlags::StdCenter() { - return wxSizerFlags().Align(wxALIGN_CENTER).DoubleBorder(); + return wxSizerFlags().Align(wxALIGN_CENTER).DoubleBorder(); } wxSizerFlags pxSizerFlags::StdExpand() { - return StdSpace().Expand(); + return StdSpace().Expand(); } // A good sizer flags setting for top-level static boxes or top-level picture boxes. @@ -252,7 +254,7 @@ wxSizerFlags pxSizerFlags::StdExpand() // manually by using a spacer. wxSizerFlags pxSizerFlags::TopLevelBox() { - return pxBorder(wxLEFT | wxBOTTOM | wxRIGHT, StdPadding).Expand(); + return pxBorder(wxLEFT | wxBOTTOM | wxRIGHT, StdPadding).Expand(); } // Flags intended for use on grouped StaticBox controls. These flags are ideal for @@ -261,9 +263,9 @@ wxSizerFlags pxSizerFlags::TopLevelBox() // "tight"). wxSizerFlags pxSizerFlags::SubGroup() { - // Groups look better with a slightly smaller margin than standard. - // (basically this accounts for the group's frame) - return pxBorder(wxLEFT | wxBOTTOM | wxRIGHT, StdPadding - 2).Expand(); + // Groups look better with a slightly smaller margin than standard. + // (basically this accounts for the group's frame) + return pxBorder(wxLEFT | wxBOTTOM | wxRIGHT, StdPadding - 2).Expand(); } // This force-aligns the std button sizer to the right, where (at least) us win32 platform @@ -271,20 +273,20 @@ wxSizerFlags pxSizerFlags::SubGroup() // just because it's *not* where win32 sticks it. Too bad! wxSizerFlags pxSizerFlags::StdButton() { - return pxBorder().Align(wxALIGN_RIGHT); + return pxBorder().Align(wxALIGN_RIGHT); } wxSizerFlags pxSizerFlags::Checkbox() { - return StdExpand(); + return StdExpand(); } void pxSizerFlags::SetBestPadding() { - if (wxSystemSettings::GetMetric(wxSYS_SCREEN_X) > 1024 && wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) > 864) - StdPadding = 4; - else - StdPadding = 1; + if (wxSystemSettings::GetMetric(wxSYS_SCREEN_X) > 1024 && wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) > 864) + StdPadding = 4; + else + StdPadding = 1; } // -------------------------------------------------------------------------------------- @@ -293,44 +295,44 @@ void pxSizerFlags::SetBestPadding() static bool is_cjk_char(const uint ch) { - /** + /** * You can check these range at http://unicode.org/charts/ * see the "East Asian Scripts" part. * Notice that not all characters in that part is still in use today, so don't list them all here. */ - // FIXME: add range from Japanese-specific and Korean-specific section if you know the - // characters are used today. + // FIXME: add range from Japanese-specific and Korean-specific section if you know the + // characters are used today. - if (ch < 0x2e80) - return false; // shortcut for common non-CJK + if (ch < 0x2e80) + return false; // shortcut for common non-CJK - return - // Han Ideographs: all except Supplement - (ch >= 0x4e00 && ch < 0x9fcf) || - (ch >= 0x3400 && ch < 0x4dbf) || - (ch >= 0x20000 && ch < 0x2a6df) || - (ch >= 0xf900 && ch < 0xfaff) || - (ch >= 0x3190 && ch < 0x319f) || + return + // Han Ideographs: all except Supplement + (ch >= 0x4e00 && ch < 0x9fcf) || + (ch >= 0x3400 && ch < 0x4dbf) || + (ch >= 0x20000 && ch < 0x2a6df) || + (ch >= 0xf900 && ch < 0xfaff) || + (ch >= 0x3190 && ch < 0x319f) || - // Radicals: all except Ideographic Description - (ch >= 0x2e80 && ch < 0x2eff) || - (ch >= 0x2f00 && ch < 0x2fdf) || - (ch >= 0x31c0 && ch < 0x31ef) || + // Radicals: all except Ideographic Description + (ch >= 0x2e80 && ch < 0x2eff) || + (ch >= 0x2f00 && ch < 0x2fdf) || + (ch >= 0x31c0 && ch < 0x31ef) || - // Chinese-specific: Bopomofo - (ch >= 0x3000 && ch < 0x303f) || + // Chinese-specific: Bopomofo + (ch >= 0x3000 && ch < 0x303f) || - // Japanese-specific: Halfwidth Katakana - (ch >= 0xff00 && ch < 0xffef) || + // Japanese-specific: Halfwidth Katakana + (ch >= 0xff00 && ch < 0xffef) || - // Japanese-specific: Hiragana, Katakana - (ch >= 0x3040 && ch <= 0x309f) || - (ch >= 0x30a0 && ch <= 0x30ff) || + // Japanese-specific: Hiragana, Katakana + (ch >= 0x3040 && ch <= 0x309f) || + (ch >= 0x30a0 && ch <= 0x30ff) || - // Korean-specific: Hangul Syllables, Halfwidth Jamo - (ch >= 0xac00 && ch < 0xd7af) || - (ch >= 0xff00 && ch < 0xffef); + // Korean-specific: Hangul Syllables, Halfwidth Jamo + (ch >= 0xac00 && ch < 0xd7af) || + (ch >= 0xff00 && ch < 0xffef); } /* @@ -350,7 +352,7 @@ static bool is_cjk_char(const uint ch) */ static bool no_break_after(const uint ch) { - // clang-format off + // clang-format off switch (ch) { /** * don't break after these Japanese/Chinese characters @@ -366,14 +368,14 @@ static bool no_break_after(const uint ch) return true; } - // clang-format on + // clang-format on - return false; + return false; } static bool no_break_before(const uint ch) { - // clang-format off + // clang-format off switch (ch) { /** * don't break before these Japanese characters @@ -403,84 +405,94 @@ static bool no_break_before(const uint ch) return true; } - // clang-format on + // clang-format on - return false; + return false; } -pxTextWrapperBase &pxTextWrapperBase::Wrap(const wxWindow &win, const wxString &text, int widthMax) +pxTextWrapperBase& pxTextWrapperBase::Wrap(const wxWindow& win, const wxString& text, int widthMax) { - if (text.empty()) - return *this; + if (text.empty()) + return *this; - bool wasWrapped = false; + bool wasWrapped = false; - wxString line; - line.reserve(text.length() + 12); + wxString line; + line.reserve(text.length() + 12); - wxString::const_iterator lastSpace = text.end(); - wxString::const_iterator lineStart = text.begin(); - for (wxString::const_iterator p = lineStart;; ++p) { - if (IsStartOfNewLine()) { - OnNewLine(); + wxString::const_iterator lastSpace = text.end(); + wxString::const_iterator lineStart = text.begin(); + for (wxString::const_iterator p = lineStart;; ++p) + { + if (IsStartOfNewLine()) + { + OnNewLine(); - lastSpace = text.end(); - lineStart = p; + lastSpace = text.end(); + lineStart = p; - if (wasWrapped) - line = m_indent; - else - line.clear(); - } + if (wasWrapped) + line = m_indent; + else + line.clear(); + } - if (p == text.end() || *p == L'\n') { - wasWrapped = false; - DoOutputLine(line); + if (p == text.end() || *p == L'\n') + { + wasWrapped = false; + DoOutputLine(line); - if (p == text.end()) - break; - } else { // not EOL - if (is_cjk_char(*p)) { - if (!no_break_before(*p)) { - if (p == lineStart || !no_break_after(*(p - 1))) - lastSpace = p; - } - } else if (*p == L' ' || *p == L',' || *p == L'/') - lastSpace = p; + if (p == text.end()) + break; + } + else + { // not EOL + if (is_cjk_char(*p)) + { + if (!no_break_before(*p)) + { + if (p == lineStart || !no_break_after(*(p - 1))) + lastSpace = p; + } + } + else if (*p == L' ' || *p == L',' || *p == L'/') + lastSpace = p; - line += *p; + line += *p; - if (widthMax >= 0 && lastSpace != text.end()) { - int width; - win.GetTextExtent(line, &width, NULL); + if (widthMax >= 0 && lastSpace != text.end()) + { + int width; + win.GetTextExtent(line, &width, NULL); - if (width > widthMax) { - wasWrapped = true; + if (width > widthMax) + { + wasWrapped = true; - // remove the last word from this line - line.erase(lastSpace - lineStart, p + 1 - lineStart); - DoOutputLine(line); + // remove the last word from this line + line.erase(lastSpace - lineStart, p + 1 - lineStart); + DoOutputLine(line); - // go back to the last word of this line which we didn't - // output yet - p = lastSpace; + // go back to the last word of this line which we didn't + // output yet + p = lastSpace; - if (*p != L' ') - p--; - } - } - //else: no wrapping at all or impossible to wrap - } - } + if (*p != L' ') + p--; + } + } + //else: no wrapping at all or impossible to wrap + } + } - return *this; + return *this; } -void pxTextWrapperBase::DoOutputLine(const wxString &line) +void pxTextWrapperBase::DoOutputLine(const wxString& line) { - OnOutputLine(line); - m_linecount++; - m_eol = true; + OnOutputLine(line); + m_linecount++; + m_eol = true; } // this function is a destructive inspector: when it returns true it also @@ -488,34 +500,34 @@ void pxTextWrapperBase::DoOutputLine(const wxString &line) // more bool pxTextWrapperBase::IsStartOfNewLine() { - if (!m_eol) - return false; + if (!m_eol) + return false; - m_eol = false; - return true; + m_eol = false; + return true; } -pxTextWrapper &pxTextWrapper::Wrap(const wxWindow &win, const wxString &text, int widthMax) +pxTextWrapper& pxTextWrapper::Wrap(const wxWindow& win, const wxString& text, int widthMax) { - _parent::Wrap(win, text, widthMax); - return *this; + _parent::Wrap(win, text, widthMax); + return *this; } -pxTextWrapper &pxTextWrapper::Wrap(const wxWindow *win, const wxString &text, int widthMax) +pxTextWrapper& pxTextWrapper::Wrap(const wxWindow* win, const wxString& text, int widthMax) { - if (win) - _parent::Wrap(*win, text, widthMax); - return *this; + if (win) + _parent::Wrap(*win, text, widthMax); + return *this; } -void pxTextWrapper::OnOutputLine(const wxString &line) +void pxTextWrapper::OnOutputLine(const wxString& line) { - m_text += line; + m_text += line; } void pxTextWrapper::OnNewLine() { - m_text += L'\n'; + m_text += L'\n'; } // -------------------------------------------------------------------------------------- @@ -527,67 +539,69 @@ BusyCursorType ScopedBusyCursor::m_defBusyType; ScopedBusyCursor::ScopedBusyCursor(BusyCursorType busytype) { - pxAssert(wxTheApp != NULL); + pxAssert(wxTheApp != NULL); - BusyCursorType curtype = Cursor_NotBusy; - if (!m_cursorStack.empty()) - curtype = m_cursorStack.top(); + BusyCursorType curtype = Cursor_NotBusy; + if (!m_cursorStack.empty()) + curtype = m_cursorStack.top(); - if (curtype < busytype) - SetManualBusyCursor(curtype = busytype); + if (curtype < busytype) + SetManualBusyCursor(curtype = busytype); - m_cursorStack.push(curtype); + m_cursorStack.push(curtype); } ScopedBusyCursor::~ScopedBusyCursor() { - if (!pxAssert(wxTheApp != NULL)) - return; + if (!pxAssert(wxTheApp != NULL)) + return; - if (!pxAssert(!m_cursorStack.empty())) { - SetManualBusyCursor(m_defBusyType); - return; - } + if (!pxAssert(!m_cursorStack.empty())) + { + SetManualBusyCursor(m_defBusyType); + return; + } - BusyCursorType curtype = m_cursorStack.top(); - m_cursorStack.pop(); + BusyCursorType curtype = m_cursorStack.top(); + m_cursorStack.pop(); - if (m_cursorStack.empty()) - SetManualBusyCursor(m_defBusyType); - else if (m_cursorStack.top() != curtype) - SetManualBusyCursor(m_cursorStack.top()); + if (m_cursorStack.empty()) + SetManualBusyCursor(m_defBusyType); + else if (m_cursorStack.top() != curtype) + SetManualBusyCursor(m_cursorStack.top()); } void ScopedBusyCursor::SetDefault(BusyCursorType busytype) { - if (busytype == m_defBusyType) - return; - m_defBusyType = busytype; + if (busytype == m_defBusyType) + return; + m_defBusyType = busytype; - if (m_cursorStack.empty()) - SetManualBusyCursor(busytype); + if (m_cursorStack.empty()) + SetManualBusyCursor(busytype); } void ScopedBusyCursor::SetManualBusyCursor(BusyCursorType busytype) { - switch (busytype) { - case Cursor_NotBusy: - wxSetCursor(wxNullCursor); - break; - case Cursor_KindaBusy: - wxSetCursor(StockCursors.GetArrowWait()); - break; - case Cursor_ReallyBusy: - wxSetCursor(*wxHOURGLASS_CURSOR); - break; - } + switch (busytype) + { + case Cursor_NotBusy: + wxSetCursor(wxNullCursor); + break; + case Cursor_KindaBusy: + wxSetCursor(StockCursors.GetArrowWait()); + break; + case Cursor_ReallyBusy: + wxSetCursor(*wxHOURGLASS_CURSOR); + break; + } } -const wxCursor &MoreStockCursors::GetArrowWait() +const wxCursor& MoreStockCursors::GetArrowWait() { - if (!m_arrowWait) - m_arrowWait = std::make_unique(wxCURSOR_ARROWWAIT); - return *m_arrowWait; + if (!m_arrowWait) + m_arrowWait = std::make_unique(wxCURSOR_ARROWWAIT); + return *m_arrowWait; } MoreStockCursors StockCursors; @@ -599,39 +613,39 @@ MoreStockCursors StockCursors; // extends the tooltip time to the maximum possible. GTK seems to have indefinite // tooltips, I don't know about OS X. -void pxSetToolTip(wxWindow *wind, const wxString &src) +void pxSetToolTip(wxWindow* wind, const wxString& src) { - if (wind == NULL) - return; // Silently ignore nulls - wind->SetToolTip(src); + if (wind == NULL) + return; // Silently ignore nulls + wind->SetToolTip(src); // Make tooltips show for as long as possible on Windows. Linux (GTK) can // show tooltips indefinitely. #ifdef __WXMSW__ - wind->GetToolTip()->SetAutoPop(32767); + wind->GetToolTip()->SetAutoPop(32767); #endif } -void pxSetToolTip(wxWindow &wind, const wxString &src) +void pxSetToolTip(wxWindow& wind, const wxString& src) { - pxSetToolTip(&wind, src); + pxSetToolTip(&wind, src); } wxFont pxGetFixedFont(int ptsize, wxFontWeight weight, bool underline) { - return wxFont( - ptsize, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, weight, underline + return wxFont( + ptsize, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, weight, underline #ifdef __WXMSW__ - , - L"Lucida Console" // better than courier new (win32 only) + , + L"Lucida Console" // better than courier new (win32 only) #endif - ); + ); } wxString pxGetAppName() { - pxAssert(wxTheApp); - return wxTheApp->GetAppName(); + pxAssert(wxTheApp); + return wxTheApp->GetAppName(); } diff --git a/common/wxGuiTools.h b/common/wxGuiTools.h index 27362138f6..2688ef9b74 100644 --- a/common/wxGuiTools.h +++ b/common/wxGuiTools.h @@ -36,17 +36,17 @@ class wxSpinCtrl; namespace pxSizerFlags { -static int StdPadding = 4; + static int StdPadding = 4; -extern wxSizerFlags StdSpace(); -extern wxSizerFlags StdCenter(); -extern wxSizerFlags StdExpand(); -extern wxSizerFlags TopLevelBox(); -extern wxSizerFlags SubGroup(); -extern wxSizerFlags StdButton(); -extern wxSizerFlags Checkbox(); -extern void SetBestPadding(); -}; + extern wxSizerFlags StdSpace(); + extern wxSizerFlags StdCenter(); + extern wxSizerFlags StdExpand(); + extern wxSizerFlags TopLevelBox(); + extern wxSizerFlags SubGroup(); + extern wxSizerFlags StdButton(); + extern wxSizerFlags Checkbox(); + extern void SetBestPadding(); +}; // namespace pxSizerFlags #define wxSF wxSizerFlags() @@ -58,118 +58,120 @@ extern void SetBestPadding(); // struct pxAlignmentType { - enum { - Centre, - Center = Centre, - Middle, - Left, - Right, - Top, - Bottom - }; + enum + { + Centre, + Center = Centre, + Middle, + Left, + Right, + Top, + Bottom + }; - int intval; + int intval; - wxSizerFlags Apply(wxSizerFlags flags = wxSizerFlags()) const; + wxSizerFlags Apply(wxSizerFlags flags = wxSizerFlags()) const; - wxSizerFlags operator&(const wxSizerFlags &_flgs) const - { - return Apply(_flgs); - } + wxSizerFlags operator&(const wxSizerFlags& _flgs) const + { + return Apply(_flgs); + } - wxSizerFlags Expand() const - { - return Apply().Expand(); - } + wxSizerFlags Expand() const + { + return Apply().Expand(); + } - wxSizerFlags Border(int dir, int padding) const - { - return Apply().Border(dir, padding); - } + wxSizerFlags Border(int dir, int padding) const + { + return Apply().Border(dir, padding); + } - wxSizerFlags Proportion() const - { - return Apply().Proportion(intval); - } + wxSizerFlags Proportion() const + { + return Apply().Proportion(intval); + } - operator wxSizerFlags() const - { - return Apply(); - } + operator wxSizerFlags() const + { + return Apply(); + } }; struct pxStretchType { - enum { - Shrink, - Expand, - Shaped, - ReserveHidden, - FixedMinimum - }; + enum + { + Shrink, + Expand, + Shaped, + ReserveHidden, + FixedMinimum + }; - int intval; + int intval; - wxSizerFlags Apply(wxSizerFlags flags = wxSizerFlags()) const; + wxSizerFlags Apply(wxSizerFlags flags = wxSizerFlags()) const; - wxSizerFlags operator&(const wxSizerFlags &_flgs) const - { - return Apply(_flgs); - } + wxSizerFlags operator&(const wxSizerFlags& _flgs) const + { + return Apply(_flgs); + } - wxSizerFlags Border(int dir, int padding) const - { - return Apply().Border(dir, padding); - } + wxSizerFlags Border(int dir, int padding) const + { + return Apply().Border(dir, padding); + } - wxSizerFlags Proportion() const - { - return Apply().Proportion(intval); - } + wxSizerFlags Proportion() const + { + return Apply().Proportion(intval); + } - operator wxSizerFlags() const - { - return Apply(); - } + operator wxSizerFlags() const + { + return Apply(); + } }; static __fi wxSizerFlags pxProportion(int prop) { - return wxSizerFlags(prop); + return wxSizerFlags(prop); } static __fi wxSizerFlags pxBorder(int dir = wxALL, int pad = pxSizerFlags::StdPadding) { - return wxSizerFlags().Border(dir, pad); + return wxSizerFlags().Border(dir, pad); } class pxStretchSpacer { public: - int proportion; + int proportion; - pxStretchSpacer(int prop = 0) - { - proportion = prop; - } + pxStretchSpacer(int prop = 0) + { + proportion = prop; + } }; extern const pxAlignmentType - pxCentre, // Horizontal centered alignment - pxCenter, - pxMiddle, // vertical centered alignment + pxCentre, // Horizontal centered alignment + pxCenter, + pxMiddle, // vertical centered alignment - pxAlignLeft, - pxAlignRight, - pxAlignTop, - pxAlignBottom; + pxAlignLeft, + pxAlignRight, + pxAlignTop, + pxAlignBottom; extern const pxStretchType - pxShrink, - pxExpand, - pxShaped, - pxReserveHidden, - pxFixedMinimum; + pxShrink, + pxExpand, + pxShaped, + pxReserveHidden, + pxFixedMinimum; // -------------------------------------------------------------------------------------- // pxWindowAndFlags @@ -188,25 +190,25 @@ extern const pxStretchType template struct pxWindowAndFlags { - WinType *window; - wxSizerFlags flags; + WinType* window; + wxSizerFlags flags; }; -extern wxSizerFlags operator&(const wxSizerFlags &_flgs, const wxSizerFlags &_flgs2); +extern wxSizerFlags operator&(const wxSizerFlags& _flgs, const wxSizerFlags& _flgs2); template ::value>::type> -pxWindowAndFlags operator|(WinType *_win, const wxSizerFlags &_flgs) +pxWindowAndFlags operator|(WinType* _win, const wxSizerFlags& _flgs) { - pxWindowAndFlags result = {_win, _flgs}; - return result; + pxWindowAndFlags result = {_win, _flgs}; + return result; } template ::value>::type> -pxWindowAndFlags operator|(WinType &_win, const wxSizerFlags &_flgs) +pxWindowAndFlags operator|(WinType& _win, const wxSizerFlags& _flgs) { - pxWindowAndFlags result = {&_win, _flgs}; - return result; + pxWindowAndFlags result = {&_win, _flgs}; + return result; } // -------------------------------------------------------------------------------------- @@ -221,51 +223,51 @@ pxWindowAndFlags operator|(WinType &_win, const wxSizerFlags &_flgs) // has no sizer set via SetSizer(), an assertion is generated. // -extern void operator+=(wxSizer &target, wxWindow *src); -extern void operator+=(wxSizer &target, wxSizer *src); -extern void operator+=(wxSizer &target, wxWindow &src); -extern void operator+=(wxSizer &target, wxSizer &src); +extern void operator+=(wxSizer& target, wxWindow* src); +extern void operator+=(wxSizer& target, wxSizer* src); +extern void operator+=(wxSizer& target, wxWindow& src); +extern void operator+=(wxSizer& target, wxSizer& src); -extern void operator+=(wxSizer *target, wxWindow &src); -extern void operator+=(wxSizer *target, wxSizer &src); +extern void operator+=(wxSizer* target, wxWindow& src); +extern void operator+=(wxSizer* target, wxSizer& src); -extern void operator+=(wxSizer &target, int spacer); -extern void operator+=(wxWindow &target, int spacer); -extern void operator+=(wxSizer &target, const pxStretchSpacer &spacer); -extern void operator+=(wxWindow &target, const pxStretchSpacer &spacer); +extern void operator+=(wxSizer& target, int spacer); +extern void operator+=(wxWindow& target, int spacer); +extern void operator+=(wxSizer& target, const pxStretchSpacer& spacer); +extern void operator+=(wxWindow& target, const pxStretchSpacer& spacer); // ---------------------------------------------------------------------------- // Important: This template is needed in order to retain window type information and // invoke the proper overloaded version of += (which is used by pxStaticText and other // classes to perform special actions when added to sizers). template -void operator+=(wxWindow &target, WinType *src) +void operator+=(wxWindow& target, WinType* src) { - if (!pxAssert(target.GetSizer() != NULL)) - return; - *target.GetSizer() += src; + if (!pxAssert(target.GetSizer() != NULL)) + return; + *target.GetSizer() += src; } template -void operator+=(wxWindow &target, WinType &src) +void operator+=(wxWindow& target, WinType& src) { - if (!pxAssert(target.GetSizer() != NULL)) - return; - *target.GetSizer() += src; + if (!pxAssert(target.GetSizer() != NULL)) + return; + *target.GetSizer() += src; } template -void operator+=(wxWindow &target, const pxWindowAndFlags &src) +void operator+=(wxWindow& target, const pxWindowAndFlags& src) { - if (!pxAssert(target.GetSizer() != NULL)) - return; - *target.GetSizer() += src; + if (!pxAssert(target.GetSizer() != NULL)) + return; + *target.GetSizer() += src; } template -void operator+=(wxSizer &target, const pxWindowAndFlags &src) +void operator+=(wxSizer& target, const pxWindowAndFlags& src) { - target.Add(src.window, src.flags); + target.Add(src.window, src.flags); } wxDECLARE_EVENT(pxEvt_OnDialogCreated, wxCommandEvent); @@ -276,219 +278,219 @@ wxDECLARE_EVENT(pxEvt_OnDialogCreated, wxCommandEvent); class pxDialogCreationFlags { public: - wxSize MinimumSize; - wxOrientation BoxSizerOrient; + wxSize MinimumSize; + wxOrientation BoxSizerOrient; - bool isResizable; - bool hasContextHelp; - bool hasCaption; - bool hasMinimizeBox; - bool hasMaximizeBox; - bool hasSystemMenu; - bool hasCloseBox; + bool isResizable; + bool hasContextHelp; + bool hasCaption; + bool hasMinimizeBox; + bool hasMaximizeBox; + bool hasSystemMenu; + bool hasCloseBox; public: - virtual ~pxDialogCreationFlags() = default; + virtual ~pxDialogCreationFlags() = default; - pxDialogCreationFlags() - { - MinimumSize = wxDefaultSize; - BoxSizerOrient = wxVERTICAL; - isResizable = false; - hasContextHelp = false; + pxDialogCreationFlags() + { + MinimumSize = wxDefaultSize; + BoxSizerOrient = wxVERTICAL; + isResizable = false; + hasContextHelp = false; - hasCloseBox = true; - hasSystemMenu = true; - hasMinimizeBox = false; - hasMaximizeBox = false; - hasCaption = true; - } + hasCloseBox = true; + hasSystemMenu = true; + hasMinimizeBox = false; + hasMaximizeBox = false; + hasCaption = true; + } - pxDialogCreationFlags &SetSizerOrient(wxOrientation orient) - { - BoxSizerOrient = orient; - return *this; - } + pxDialogCreationFlags& SetSizerOrient(wxOrientation orient) + { + BoxSizerOrient = orient; + return *this; + } - pxDialogCreationFlags &SetResize(bool enable = true) - { - isResizable = enable; - return *this; - } + pxDialogCreationFlags& SetResize(bool enable = true) + { + isResizable = enable; + return *this; + } - pxDialogCreationFlags &SetMinimize(bool enable = true) - { - hasMinimizeBox = enable; - return *this; - } + pxDialogCreationFlags& SetMinimize(bool enable = true) + { + hasMinimizeBox = enable; + return *this; + } - pxDialogCreationFlags &SetMaximize(bool enable = true) - { - hasMaximizeBox = enable; - return *this; - } + pxDialogCreationFlags& SetMaximize(bool enable = true) + { + hasMaximizeBox = enable; + return *this; + } - // NOTE: Enabling system menu on dialogs usually doesn't work, and might cause - // other unwanted behavior, such as a missing close button. - pxDialogCreationFlags &SetSystemMenu(bool enable = true) - { - hasSystemMenu = enable; - return *this; - } + // NOTE: Enabling system menu on dialogs usually doesn't work, and might cause + // other unwanted behavior, such as a missing close button. + pxDialogCreationFlags& SetSystemMenu(bool enable = true) + { + hasSystemMenu = enable; + return *this; + } - pxDialogCreationFlags &SetCaption(bool enable = true) - { - hasCaption = enable; - return *this; - } + pxDialogCreationFlags& SetCaption(bool enable = true) + { + hasCaption = enable; + return *this; + } - pxDialogCreationFlags &SetCloseBox(bool enable = true) - { - hasCloseBox = enable; - return *this; - } + pxDialogCreationFlags& SetCloseBox(bool enable = true) + { + hasCloseBox = enable; + return *this; + } - pxDialogCreationFlags SetContextHelp(bool enabled = true) - { - hasContextHelp = enabled; - return *this; - } + pxDialogCreationFlags SetContextHelp(bool enabled = true) + { + hasContextHelp = enabled; + return *this; + } - pxDialogCreationFlags &SetMinWidth(int width) - { - if (width > MinimumSize.x) - MinimumSize.SetWidth(width); - return *this; - } + pxDialogCreationFlags& SetMinWidth(int width) + { + if (width > MinimumSize.x) + MinimumSize.SetWidth(width); + return *this; + } - pxDialogCreationFlags &SetMinHeight(int height) - { - if (height > MinimumSize.y) - MinimumSize.SetHeight(height); - return *this; - } + pxDialogCreationFlags& SetMinHeight(int height) + { + if (height > MinimumSize.y) + MinimumSize.SetHeight(height); + return *this; + } - pxDialogCreationFlags &SetMinSize(const wxSize &size) - { - return SetMinWidth(size.x).SetMinHeight(size.y); - } + pxDialogCreationFlags& SetMinSize(const wxSize& size) + { + return SetMinWidth(size.x).SetMinHeight(size.y); + } - pxDialogCreationFlags Horizontal() const - { - return pxDialogCreationFlags(*this).SetSizerOrient(wxHORIZONTAL); - } + pxDialogCreationFlags Horizontal() const + { + return pxDialogCreationFlags(*this).SetSizerOrient(wxHORIZONTAL); + } - pxDialogCreationFlags Vertical() const - { - return pxDialogCreationFlags(*this).SetSizerOrient(wxVERTICAL); - } + pxDialogCreationFlags Vertical() const + { + return pxDialogCreationFlags(*this).SetSizerOrient(wxVERTICAL); + } - pxDialogCreationFlags NoSizer() const - { - return pxDialogCreationFlags(*this).SetSizerOrient((wxOrientation)0); - } + pxDialogCreationFlags NoSizer() const + { + return pxDialogCreationFlags(*this).SetSizerOrient((wxOrientation)0); + } - pxDialogCreationFlags Resize(bool enable = true) const - { - return pxDialogCreationFlags(*this).SetResize(enable); - } + pxDialogCreationFlags Resize(bool enable = true) const + { + return pxDialogCreationFlags(*this).SetResize(enable); + } - pxDialogCreationFlags Minimize(bool enable = true) const - { - return pxDialogCreationFlags(*this).SetMinimize(enable); - } + pxDialogCreationFlags Minimize(bool enable = true) const + { + return pxDialogCreationFlags(*this).SetMinimize(enable); + } - pxDialogCreationFlags Maximize(bool enable = true) const - { - return pxDialogCreationFlags(*this).SetMaximize(enable); - } + pxDialogCreationFlags Maximize(bool enable = true) const + { + return pxDialogCreationFlags(*this).SetMaximize(enable); + } - // NOTE: Enabling system menu on dialogs usually doesn't work, and might cause - // other unwanted behavior, such as a missing close button. - pxDialogCreationFlags SystemMenu(bool enable = true) const - { - return pxDialogCreationFlags(*this).SetSystemMenu(false); - } + // NOTE: Enabling system menu on dialogs usually doesn't work, and might cause + // other unwanted behavior, such as a missing close button. + pxDialogCreationFlags SystemMenu(bool enable = true) const + { + return pxDialogCreationFlags(*this).SetSystemMenu(false); + } - pxDialogCreationFlags Caption(bool enable = true) const - { - return pxDialogCreationFlags(*this).SetCaption(enable); - } + pxDialogCreationFlags Caption(bool enable = true) const + { + return pxDialogCreationFlags(*this).SetCaption(enable); + } - pxDialogCreationFlags CloseBox(bool enable = true) const - { - return pxDialogCreationFlags(*this).SetCloseBox(enable); - } + pxDialogCreationFlags CloseBox(bool enable = true) const + { + return pxDialogCreationFlags(*this).SetCloseBox(enable); + } - pxDialogCreationFlags NoResize() const - { - return pxDialogCreationFlags(*this).SetResize(false); - } + pxDialogCreationFlags NoResize() const + { + return pxDialogCreationFlags(*this).SetResize(false); + } - pxDialogCreationFlags NoMinimize() const - { - return pxDialogCreationFlags(*this).SetMinimize(false); - } + pxDialogCreationFlags NoMinimize() const + { + return pxDialogCreationFlags(*this).SetMinimize(false); + } - pxDialogCreationFlags NoMaximize() const - { - return pxDialogCreationFlags(*this).SetMaximize(false); - } + pxDialogCreationFlags NoMaximize() const + { + return pxDialogCreationFlags(*this).SetMaximize(false); + } - pxDialogCreationFlags NoSystemMenu() const - { - return pxDialogCreationFlags(*this).SetSystemMenu(false); - } + pxDialogCreationFlags NoSystemMenu() const + { + return pxDialogCreationFlags(*this).SetSystemMenu(false); + } - pxDialogCreationFlags NoCaption() const - { - return pxDialogCreationFlags(*this).SetCaption(false); - } + pxDialogCreationFlags NoCaption() const + { + return pxDialogCreationFlags(*this).SetCaption(false); + } - pxDialogCreationFlags NoCloseBox() const - { - return pxDialogCreationFlags(*this).SetCloseBox(false); - } + pxDialogCreationFlags NoCloseBox() const + { + return pxDialogCreationFlags(*this).SetCloseBox(false); + } - pxDialogCreationFlags MinWidth(int width) const - { - return pxDialogCreationFlags(*this).SetMinWidth(width); - } + pxDialogCreationFlags MinWidth(int width) const + { + return pxDialogCreationFlags(*this).SetMinWidth(width); + } - pxDialogCreationFlags MinHeight(int height) const - { - return pxDialogCreationFlags(*this).SetMinHeight(height); - } + pxDialogCreationFlags MinHeight(int height) const + { + return pxDialogCreationFlags(*this).SetMinHeight(height); + } - pxDialogCreationFlags MinSize(const wxSize &size) const - { - return pxDialogCreationFlags(*this).SetMinSize(size); - } + pxDialogCreationFlags MinSize(const wxSize& size) const + { + return pxDialogCreationFlags(*this).SetMinSize(size); + } - pxDialogCreationFlags MinSize(int width, int height) const - { - return pxDialogCreationFlags(*this).SetMinWidth(width).SetMinHeight(height); - } + pxDialogCreationFlags MinSize(int width, int height) const + { + return pxDialogCreationFlags(*this).SetMinWidth(width).SetMinHeight(height); + } - int GetWxWindowFlags() const - { - int retval = 0; - if (isResizable) - retval |= wxRESIZE_BORDER; - if (hasCaption) - retval |= wxCAPTION; - if (hasMaximizeBox) - retval |= wxMAXIMIZE_BOX; - if (hasMinimizeBox) - retval |= wxMINIMIZE_BOX; - if (hasSystemMenu) - retval |= wxSYSTEM_MENU; - if (hasCloseBox) - retval |= wxCLOSE_BOX; + int GetWxWindowFlags() const + { + int retval = 0; + if (isResizable) + retval |= wxRESIZE_BORDER; + if (hasCaption) + retval |= wxCAPTION; + if (hasMaximizeBox) + retval |= wxMAXIMIZE_BOX; + if (hasMinimizeBox) + retval |= wxMINIMIZE_BOX; + if (hasSystemMenu) + retval |= wxSYSTEM_MENU; + if (hasCloseBox) + retval |= wxCLOSE_BOX; - return retval; - } + return retval; + } }; // -------------------------------------------------------------------------------------- @@ -496,50 +498,50 @@ public: // -------------------------------------------------------------------------------------- class wxDialogWithHelpers : public wxDialog { - typedef wxDialog _parent; - wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxDialogWithHelpers); + typedef wxDialog _parent; + wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxDialogWithHelpers); protected: - bool m_hasContextHelp; - wxBoxSizer *m_extraButtonSizer; - wxRect m_CreatedRect; + bool m_hasContextHelp; + wxBoxSizer* m_extraButtonSizer; + wxRect m_CreatedRect; public: - wxDialogWithHelpers(); - wxDialogWithHelpers(wxWindow *parent, const wxString &title, const pxDialogCreationFlags &cflags = pxDialogCreationFlags()); - virtual ~wxDialogWithHelpers() = default; + wxDialogWithHelpers(); + wxDialogWithHelpers(wxWindow* parent, const wxString& title, const pxDialogCreationFlags& cflags = pxDialogCreationFlags()); + virtual ~wxDialogWithHelpers() = default; - void Init(const pxDialogCreationFlags &cflags); - void AddOkCancel(wxSizer &sizer, bool hasApply = false); - void AddOkCancel(wxSizer *sizer = NULL, bool hasApply = false); - void RememberPosition(); + void Init(const pxDialogCreationFlags& cflags); + void AddOkCancel(wxSizer& sizer, bool hasApply = false); + void AddOkCancel(wxSizer* sizer = NULL, bool hasApply = false); + void RememberPosition(); - virtual void SmartCenterFit(); - virtual int ShowModal(); - virtual bool Show(bool show = true); + virtual void SmartCenterFit(); + virtual int ShowModal(); + virtual bool Show(bool show = true); - // Must return the same thing as GetNameStatic; a name ideal for use in uniquely - // identifying dialogs. (this version is the 'instance' version, which is called - // by BaseConfigurationDialog to assign the wxWidgets dialog name, and for saving - // screenshots to disk) - virtual wxString GetDialogName() const; + // Must return the same thing as GetNameStatic; a name ideal for use in uniquely + // identifying dialogs. (this version is the 'instance' version, which is called + // by BaseConfigurationDialog to assign the wxWidgets dialog name, and for saving + // screenshots to disk) + virtual wxString GetDialogName() const; - virtual wxStaticText &Label(const wxString &label); - virtual pxStaticText &Text(const wxString &label); - virtual pxStaticText &Heading(const wxString &label); + virtual wxStaticText& Label(const wxString& label); + virtual pxStaticText& Text(const wxString& label); + virtual pxStaticText& Heading(const wxString& label); - wxDialogWithHelpers &SetMinWidth(int newWidth); - wxDialogWithHelpers &SetMinHeight(int newHeight); + wxDialogWithHelpers& SetMinWidth(int newWidth); + wxDialogWithHelpers& SetMinHeight(int newHeight); - int GetCharHeight() const; + int GetCharHeight() const; protected: - void OnDialogCreated(wxCommandEvent &evt); - void OnOkCancel(wxCommandEvent &evt); + void OnDialogCreated(wxCommandEvent& evt); + void OnOkCancel(wxCommandEvent& evt); - bool ShouldPreventAppExit() const { return false; } + bool ShouldPreventAppExit() const { return false; } - void DoAutoCenter(); + void DoAutoCenter(); }; // -------------------------------------------------------------------------------------- @@ -561,24 +563,24 @@ protected: // class wxPanelWithHelpers : public wxPanel { - wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxPanelWithHelpers); + wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxPanelWithHelpers); public: - wxPanelWithHelpers(wxWindow *parent, wxOrientation orient, const wxString &staticBoxLabel); - wxPanelWithHelpers(wxWindow *parent, wxOrientation orient); - wxPanelWithHelpers(wxWindow *parent, const wxPoint &pos, const wxSize &size = wxDefaultSize); - explicit wxPanelWithHelpers(wxWindow *parent = NULL); + wxPanelWithHelpers(wxWindow* parent, wxOrientation orient, const wxString& staticBoxLabel); + wxPanelWithHelpers(wxWindow* parent, wxOrientation orient); + wxPanelWithHelpers(wxWindow* parent, const wxPoint& pos, const wxSize& size = wxDefaultSize); + explicit wxPanelWithHelpers(wxWindow* parent = NULL); - wxPanelWithHelpers *AddFrame(const wxString &label, wxOrientation orient = wxVERTICAL); + wxPanelWithHelpers* AddFrame(const wxString& label, wxOrientation orient = wxVERTICAL); - wxStaticText &Label(const wxString &label); - pxStaticText &Text(const wxString &label); - pxStaticText &Heading(const wxString &label); + wxStaticText& Label(const wxString& label); + pxStaticText& Text(const wxString& label); + pxStaticText& Heading(const wxString& label); - virtual wxPanelWithHelpers &SetMinWidth(int newWidth); + virtual wxPanelWithHelpers& SetMinWidth(int newWidth); protected: - void Init(); + void Init(); }; @@ -596,38 +598,38 @@ protected: class pxTextWrapperBase { protected: - bool m_eol; - int m_linecount; - wxString m_indent; + bool m_eol; + int m_linecount; + wxString m_indent; public: - virtual ~pxTextWrapperBase() = default; + virtual ~pxTextWrapperBase() = default; - pxTextWrapperBase(const wxString &indent = wxEmptyString) - : m_indent(indent) - { - m_eol = false; - m_linecount = 0; - } + pxTextWrapperBase(const wxString& indent = wxEmptyString) + : m_indent(indent) + { + m_eol = false; + m_linecount = 0; + } - // win is used for getting the font, text is the text to wrap, width is the - // max line width or -1 to disable wrapping - pxTextWrapperBase &Wrap(const wxWindow &win, const wxString &text, int widthMax); + // win is used for getting the font, text is the text to wrap, width is the + // max line width or -1 to disable wrapping + pxTextWrapperBase& Wrap(const wxWindow& win, const wxString& text, int widthMax); - int GetLineCount() const - { - return m_linecount; - } + int GetLineCount() const + { + return m_linecount; + } protected: - // line may be empty - virtual void OnOutputLine(const wxString &line) {} + // line may be empty + virtual void OnOutputLine(const wxString& line) {} - // called at the start of every new line (except the very first one) - virtual void OnNewLine() {} + // called at the start of every new line (except the very first one) + virtual void OnNewLine() {} - void DoOutputLine(const wxString &line); - bool IsStartOfNewLine(); + void DoOutputLine(const wxString& line); + bool IsStartOfNewLine(); }; // -------------------------------------------------------------------------------------- @@ -638,30 +640,30 @@ protected: // class pxTextWrapper : public pxTextWrapperBase { - typedef pxTextWrapperBase _parent; + typedef pxTextWrapperBase _parent; protected: - wxString m_text; + wxString m_text; public: - pxTextWrapper(const wxString &wrapPrefix = wxEmptyString) - : pxTextWrapperBase(wrapPrefix) - { - } + pxTextWrapper(const wxString& wrapPrefix = wxEmptyString) + : pxTextWrapperBase(wrapPrefix) + { + } - virtual ~pxTextWrapper() = default; + virtual ~pxTextWrapper() = default; - const wxString &GetResult() const - { - return m_text; - } + const wxString& GetResult() const + { + return m_text; + } - pxTextWrapper &Wrap(const wxWindow &win, const wxString &text, int widthMax); - pxTextWrapper &Wrap(const wxWindow *win, const wxString &text, int widthMax); + pxTextWrapper& Wrap(const wxWindow& win, const wxString& text, int widthMax); + pxTextWrapper& Wrap(const wxWindow* win, const wxString& text, int widthMax); protected: - void OnOutputLine(const wxString &line); - void OnNewLine(); + void OnOutputLine(const wxString& line); + void OnNewLine(); }; // -------------------------------------------------------------------------------------- @@ -670,63 +672,63 @@ protected: class pxWindowTextWriter { protected: - wxDC &m_dc; + wxDC& m_dc; - wxAlignment m_align; - wxPoint m_curpos; - int m_leading; + wxAlignment m_align; + wxPoint m_curpos; + int m_leading; - virtual void _DoWriteLn(const wxString &msg); - void _DoWrite(const wxChar *msg); + virtual void _DoWriteLn(const wxString& msg); + void _DoWrite(const wxChar* msg); public: - pxWindowTextWriter(wxDC &dc); - virtual ~pxWindowTextWriter() = default; + pxWindowTextWriter(wxDC& dc); + virtual ~pxWindowTextWriter() = default; - virtual void OnFontChanged(); + virtual void OnFontChanged(); - pxWindowTextWriter &WriteLn(); - pxWindowTextWriter &FormatLn(const wxChar *fmt, ...); - pxWindowTextWriter &WriteLn(const wxChar *fmt); - pxWindowTextWriter &SetFont(const wxFont &font); - pxWindowTextWriter &Align(const wxAlignment &align); - pxWindowTextWriter &WriteLn(const wxString fmt); + pxWindowTextWriter& WriteLn(); + pxWindowTextWriter& FormatLn(const wxChar* fmt, ...); + pxWindowTextWriter& WriteLn(const wxChar* fmt); + pxWindowTextWriter& SetFont(const wxFont& font); + pxWindowTextWriter& Align(const wxAlignment& align); + pxWindowTextWriter& WriteLn(const wxString fmt); - pxWindowTextWriter &SetLeading(int lead) - { - m_leading = lead; - return *this; - } + pxWindowTextWriter& SetLeading(int lead) + { + m_leading = lead; + return *this; + } - pxWindowTextWriter &SetWeight(wxFontWeight weight); - pxWindowTextWriter &SetStyle(wxFontStyle style); - pxWindowTextWriter &Normal(); + pxWindowTextWriter& SetWeight(wxFontWeight weight); + pxWindowTextWriter& SetStyle(wxFontStyle style); + pxWindowTextWriter& Normal(); - pxWindowTextWriter &Bold() - { - return SetWeight(wxFONTWEIGHT_BOLD); - } + pxWindowTextWriter& Bold() + { + return SetWeight(wxFONTWEIGHT_BOLD); + } - pxWindowTextWriter &Italic() - { - return SetStyle(wxFONTSTYLE_ITALIC); - } + pxWindowTextWriter& Italic() + { + return SetStyle(wxFONTSTYLE_ITALIC); + } - pxWindowTextWriter &SetPos(const wxPoint &pos); - pxWindowTextWriter &MovePos(const wxSize &delta); + pxWindowTextWriter& SetPos(const wxPoint& pos); + pxWindowTextWriter& MovePos(const wxSize& delta); - pxWindowTextWriter &SetPos(int xpos, int ypos) - { - return SetPos(wxPoint(xpos, ypos)); - } + pxWindowTextWriter& SetPos(int xpos, int ypos) + { + return SetPos(wxPoint(xpos, ypos)); + } - pxWindowTextWriter &MovePos(int xdelta, int ydelta) - { - return MovePos(wxSize(xdelta, ydelta)); - } + pxWindowTextWriter& MovePos(int xdelta, int ydelta) + { + return MovePos(wxSize(xdelta, ydelta)); + } - pxWindowTextWriter &SetY(int ypos); - pxWindowTextWriter &MoveY(int ydelta); + pxWindowTextWriter& SetY(int ypos); + pxWindowTextWriter& MoveY(int ydelta); }; // -------------------------------------------------------------------------------------- @@ -737,18 +739,19 @@ public: class MoreStockCursors { protected: - std::unique_ptr m_arrowWait; + std::unique_ptr m_arrowWait; public: - MoreStockCursors() {} - virtual ~MoreStockCursors() = default; - const wxCursor &GetArrowWait(); + MoreStockCursors() {} + virtual ~MoreStockCursors() = default; + const wxCursor& GetArrowWait(); }; -enum BusyCursorType { - Cursor_NotBusy, - Cursor_KindaBusy, - Cursor_ReallyBusy, +enum BusyCursorType +{ + Cursor_NotBusy, + Cursor_KindaBusy, + Cursor_ReallyBusy, }; extern MoreStockCursors StockCursors; @@ -762,15 +765,15 @@ extern MoreStockCursors StockCursors; class ScopedBusyCursor { protected: - static std::stack m_cursorStack; - static BusyCursorType m_defBusyType; + static std::stack m_cursorStack; + static BusyCursorType m_defBusyType; public: - ScopedBusyCursor(BusyCursorType busytype); - virtual ~ScopedBusyCursor(); + ScopedBusyCursor(BusyCursorType busytype); + virtual ~ScopedBusyCursor(); - static void SetDefault(BusyCursorType busytype); - static void SetManualBusyCursor(BusyCursorType busytype); + static void SetDefault(BusyCursorType busytype); + static void SetManualBusyCursor(BusyCursorType busytype); }; // -------------------------------------------------------------------------------------- @@ -779,23 +782,23 @@ public: // Fits a given text or spinner control to the number of digits requested, since by default // they're usually way over-sized. -extern void pxFitToDigits(wxWindow *win, int digits); -extern void pxFitToDigits(wxSpinCtrl *win, int digits); -extern wxTextCtrl *CreateNumericalTextCtrl(wxWindow *parent, int digits, long flags = wxTE_RIGHT); +extern void pxFitToDigits(wxWindow* win, int digits); +extern void pxFitToDigits(wxSpinCtrl* win, int digits); +extern wxTextCtrl* CreateNumericalTextCtrl(wxWindow* parent, int digits, long flags = wxTE_RIGHT); ////////////////////////////////////////////////////////////////////////////////////////////// -extern bool pxDialogExists(const wxString &name); -extern bool pxIsValidWindowPosition(const wxWindow &window, const wxPoint &windowPos); +extern bool pxDialogExists(const wxString& name); +extern bool pxIsValidWindowPosition(const wxWindow& window, const wxPoint& windowPos); extern wxRect wxGetDisplayArea(); extern wxString pxGetAppName(); -extern int pxGetCharHeight(const wxWindow *wind, int rows = 1); -extern int pxGetCharHeight(const wxWindow &wind, int rows = 1); +extern int pxGetCharHeight(const wxWindow* wind, int rows = 1); +extern int pxGetCharHeight(const wxWindow& wind, int rows = 1); -extern void pxSetToolTip(wxWindow *wind, const wxString &src); -extern void pxSetToolTip(wxWindow &wind, const wxString &src); +extern void pxSetToolTip(wxWindow* wind, const wxString& src); +extern void pxSetToolTip(wxWindow& wind, const wxString& src); extern wxFont pxGetFixedFont(int ptsize = 8, wxFontWeight weight = wxFONTWEIGHT_NORMAL, bool underline = false); extern pxDialogCreationFlags pxDialogFlags(); diff --git a/common/wxHelpers.cpp b/common/wxHelpers.cpp index caefe1f7af..a75b3699cc 100644 --- a/common/wxHelpers.cpp +++ b/common/wxHelpers.cpp @@ -26,7 +26,7 @@ using namespace pxSizerFlags; pxDialogCreationFlags pxDialogFlags() { - return pxDialogCreationFlags().CloseBox().Caption().Vertical(); + return pxDialogCreationFlags().CloseBox().Caption().Vertical(); } @@ -38,13 +38,13 @@ pxDialogCreationFlags pxDialogFlags() // bool BaseDeletableObject::MarkForDeletion() { - return !m_IsBeingDeleted.exchange(true); + return !m_IsBeingDeleted.exchange(true); } void BaseDeletableObject::DeleteSelf() { - if (MarkForDeletion()) - DoDeletion(); + if (MarkForDeletion()) + DoDeletion(); } BaseDeletableObject::BaseDeletableObject() @@ -55,12 +55,12 @@ BaseDeletableObject::BaseDeletableObject() //pxAssertDev( _CrtIsValidHeapPointer( this ), "BaseDeletableObject types cannot be created on the stack or as temporaries!" ); #endif - m_IsBeingDeleted.store(false, std::memory_order_relaxed); + m_IsBeingDeleted.store(false, std::memory_order_relaxed); } BaseDeletableObject::~BaseDeletableObject() { - AffinityAssert_AllowFrom_MainUI(); + AffinityAssert_AllowFrom_MainUI(); } @@ -69,37 +69,37 @@ BaseDeletableObject::~BaseDeletableObject() // Creates a text control which is right-justified and has it's minimum width configured to suit // the number of digits requested. -wxTextCtrl *CreateNumericalTextCtrl(wxWindow *parent, int digits, long flags) +wxTextCtrl* CreateNumericalTextCtrl(wxWindow* parent, int digits, long flags) { - wxTextCtrl *ctrl = new wxTextCtrl(parent, wxID_ANY); - ctrl->SetWindowStyleFlag(flags); - pxFitToDigits(ctrl, digits); - return ctrl; + wxTextCtrl* ctrl = new wxTextCtrl(parent, wxID_ANY); + ctrl->SetWindowStyleFlag(flags); + pxFitToDigits(ctrl, digits); + return ctrl; } -void pxFitToDigits(wxWindow *win, int digits) +void pxFitToDigits(wxWindow* win, int digits) { - int ex; - win->GetTextExtent(wxString(L'0', digits + 1), &ex, NULL); - win->SetMinSize(wxSize(ex + 10, wxDefaultCoord)); // +10 for text control borders/insets and junk. + int ex; + win->GetTextExtent(wxString(L'0', digits + 1), &ex, NULL); + win->SetMinSize(wxSize(ex + 10, wxDefaultCoord)); // +10 for text control borders/insets and junk. } -void pxFitToDigits(wxSpinCtrl *win, int digits) +void pxFitToDigits(wxSpinCtrl* win, int digits) { - // HACK!! The better way would be to create a pxSpinCtrl class that extends wxSpinCtrl and thus - // have access to wxSpinButton::DoGetBestSize(). But since I don't want to do that, we'll just - // make/fake it with a value it's pretty common to Win32/GTK/Mac: + // HACK!! The better way would be to create a pxSpinCtrl class that extends wxSpinCtrl and thus + // have access to wxSpinButton::DoGetBestSize(). But since I don't want to do that, we'll just + // make/fake it with a value it's pretty common to Win32/GTK/Mac: - static const int MagicSpinnerSize = 18; + static const int MagicSpinnerSize = 18; - int ex; - win->GetTextExtent(wxString(L'0', digits + 1), &ex, NULL); - win->SetMinSize(wxSize(ex + 10 + MagicSpinnerSize, wxDefaultCoord)); // +10 for text control borders/insets and junk. + int ex; + win->GetTextExtent(wxString(L'0', digits + 1), &ex, NULL); + win->SetMinSize(wxSize(ex + 10 + MagicSpinnerSize, wxDefaultCoord)); // +10 for text control borders/insets and junk. } -bool pxDialogExists(const wxString &name) +bool pxDialogExists(const wxString& name) { - return wxFindWindowByName(name) != NULL; + return wxFindWindowByName(name) != NULL; } // ===================================================================================================== @@ -112,118 +112,125 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxDialogWithHelpers, wxDialog); wxDialogWithHelpers::wxDialogWithHelpers() { - m_hasContextHelp = false; - m_extraButtonSizer = NULL; + m_hasContextHelp = false; + m_extraButtonSizer = NULL; - Init(pxDialogFlags()); + Init(pxDialogFlags()); } -wxDialogWithHelpers::wxDialogWithHelpers(wxWindow *parent, const wxString &title, const pxDialogCreationFlags &cflags) - : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, cflags.GetWxWindowFlags()) +wxDialogWithHelpers::wxDialogWithHelpers(wxWindow* parent, const wxString& title, const pxDialogCreationFlags& cflags) + : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, cflags.GetWxWindowFlags()) { - m_hasContextHelp = cflags.hasContextHelp; - if ((int)cflags.BoxSizerOrient != 0) { - SetSizer(new wxBoxSizer(cflags.BoxSizerOrient)); - *this += StdPadding; - } + m_hasContextHelp = cflags.hasContextHelp; + if ((int)cflags.BoxSizerOrient != 0) + { + SetSizer(new wxBoxSizer(cflags.BoxSizerOrient)); + *this += StdPadding; + } - Init(cflags); - SetMinSize(cflags.MinimumSize); + Init(cflags); + SetMinSize(cflags.MinimumSize); } -void wxDialogWithHelpers::Init(const pxDialogCreationFlags &cflags) +void wxDialogWithHelpers::Init(const pxDialogCreationFlags& cflags) { // Note to self: if any comments indicate platform specific behaviour then // ifdef them out to see if they fix the issue. I wasted too much time // figuring out why the close box wouldn't work on wxGTK modal dialogs that // had a minimise button. #if _WIN32 - // This fixes it so that the dialogs show up in the task bar in Vista: - // (otherwise they go stupid iconized mode if the user minimizes them) - if (cflags.hasMinimizeBox) - SetExtraStyle(GetExtraStyle() & ~wxTOPLEVEL_EX_DIALOG); + // This fixes it so that the dialogs show up in the task bar in Vista: + // (otherwise they go stupid iconized mode if the user minimizes them) + if (cflags.hasMinimizeBox) + SetExtraStyle(GetExtraStyle() & ~wxTOPLEVEL_EX_DIALOG); #endif - m_extraButtonSizer = NULL; + m_extraButtonSizer = NULL; - if (m_hasContextHelp) - delete wxHelpProvider::Set(new wxSimpleHelpProvider()); + if (m_hasContextHelp) + delete wxHelpProvider::Set(new wxSimpleHelpProvider()); - Bind(pxEvt_OnDialogCreated, &wxDialogWithHelpers::OnDialogCreated, this); + Bind(pxEvt_OnDialogCreated, &wxDialogWithHelpers::OnDialogCreated, this); - Bind(wxEVT_BUTTON, &wxDialogWithHelpers::OnOkCancel, this, wxID_OK); - Bind(wxEVT_BUTTON, &wxDialogWithHelpers::OnOkCancel, this, wxID_CANCEL); + Bind(wxEVT_BUTTON, &wxDialogWithHelpers::OnOkCancel, this, wxID_OK); + Bind(wxEVT_BUTTON, &wxDialogWithHelpers::OnOkCancel, this, wxID_CANCEL); - wxCommandEvent createEvent(pxEvt_OnDialogCreated); - createEvent.SetId(GetId()); - AddPendingEvent(createEvent); + wxCommandEvent createEvent(pxEvt_OnDialogCreated); + createEvent.SetId(GetId()); + AddPendingEvent(createEvent); } -void wxDialogWithHelpers::OnDialogCreated(wxCommandEvent &evt) +void wxDialogWithHelpers::OnDialogCreated(wxCommandEvent& evt) { - evt.Skip(); - if ((evt.GetId() == GetId()) && !GetDialogName().IsEmpty()) - SetName(L"Dialog:" + GetDialogName()); + evt.Skip(); + if ((evt.GetId() == GetId()) && !GetDialogName().IsEmpty()) + SetName(L"Dialog:" + GetDialogName()); } wxString wxDialogWithHelpers::GetDialogName() const { - return wxEmptyString; + return wxEmptyString; } void wxDialogWithHelpers::DoAutoCenter() { - // Smart positioning logic! If our parent window is larger than our window by some - // good amount, then we center on that. If not, center relative to the screen. This - // avoids the popup automatically eclipsing the parent window (which happens in PCSX2 - // a lot since the main window is small). + // Smart positioning logic! If our parent window is larger than our window by some + // good amount, then we center on that. If not, center relative to the screen. This + // avoids the popup automatically eclipsing the parent window (which happens in PCSX2 + // a lot since the main window is small). - bool centerfail = true; - if (wxWindow *parent = GetParent()) { - const wxSize parentSize(parent->GetSize()); + bool centerfail = true; + if (wxWindow* parent = GetParent()) + { + const wxSize parentSize(parent->GetSize()); - if ((parentSize.x > ((int)GetSize().x * 1.5)) || (parentSize.y > ((int)GetSize().y * 1.5))) { - CenterOnParent(); - centerfail = false; - } - } + if ((parentSize.x > ((int)GetSize().x * 1.5)) || (parentSize.y > ((int)GetSize().y * 1.5))) + { + CenterOnParent(); + centerfail = false; + } + } - if (centerfail) - CenterOnScreen(); + if (centerfail) + CenterOnScreen(); } void wxDialogWithHelpers::SmartCenterFit() { - Fit(); + Fit(); - const wxString dlgName(GetDialogName()); - if (dlgName.IsEmpty()) { - DoAutoCenter(); - return; - } + const wxString dlgName(GetDialogName()); + if (dlgName.IsEmpty()) + { + DoAutoCenter(); + return; + } - if (wxConfigBase *cfg = wxConfigBase::Get(false)) { - wxRect screenRect(GetScreenRect()); + if (wxConfigBase* cfg = wxConfigBase::Get(false)) + { + wxRect screenRect(GetScreenRect()); - IniLoader loader(cfg); - ScopedIniGroup group(loader, L"DialogPositions"); - cfg->SetRecordDefaults(false); + IniLoader loader(cfg); + ScopedIniGroup group(loader, L"DialogPositions"); + cfg->SetRecordDefaults(false); - if (GetWindowStyle() & wxRESIZE_BORDER) { - wxSize size; - loader.Entry(dlgName + L"_Size", size, screenRect.GetSize()); - SetSize(size); - } + if (GetWindowStyle() & wxRESIZE_BORDER) + { + wxSize size; + loader.Entry(dlgName + L"_Size", size, screenRect.GetSize()); + SetSize(size); + } - if (!cfg->Exists(dlgName + L"_Pos")) - DoAutoCenter(); - else { - wxPoint pos; - loader.Entry(dlgName + L"_Pos", pos, screenRect.GetPosition()); - SetPosition(pos); - } - cfg->SetRecordDefaults(true); - } + if (!cfg->Exists(dlgName + L"_Pos")) + DoAutoCenter(); + else + { + wxPoint pos; + loader.Entry(dlgName + L"_Pos", pos, screenRect.GetPosition()); + SetPosition(pos); + } + cfg->SetRecordDefaults(true); + } } // Overrides wxDialog behavior to include automatic Fit() and CenterOnParent/Screen. The centering @@ -231,9 +238,9 @@ void wxDialogWithHelpers::SmartCenterFit() // 75% larger than the fitted dialog. int wxDialogWithHelpers::ShowModal() { - SmartCenterFit(); - m_CreatedRect = GetScreenRect(); - return wxDialog::ShowModal(); + SmartCenterFit(); + m_CreatedRect = GetScreenRect(); + return wxDialog::ShowModal(); } // Overrides wxDialog behavior to include automatic Fit() and CenterOnParent/Screen. The centering @@ -241,126 +248,131 @@ int wxDialogWithHelpers::ShowModal() // 75% larger than the fitted dialog. bool wxDialogWithHelpers::Show(bool show) { - if (show) { - SmartCenterFit(); - m_CreatedRect = GetScreenRect(); - } - return wxDialog::Show(show); + if (show) + { + SmartCenterFit(); + m_CreatedRect = GetScreenRect(); + } + return wxDialog::Show(show); } -wxStaticText &wxDialogWithHelpers::Label(const wxString &label) +wxStaticText& wxDialogWithHelpers::Label(const wxString& label) { - return *new wxStaticText(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_VERTICAL); + return *new wxStaticText(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_VERTICAL); } -pxStaticText &wxDialogWithHelpers::Text(const wxString &label) +pxStaticText& wxDialogWithHelpers::Text(const wxString& label) { - return *new pxStaticText(this, label); + return *new pxStaticText(this, label); } -pxStaticText &wxDialogWithHelpers::Heading(const wxString &label) +pxStaticText& wxDialogWithHelpers::Heading(const wxString& label) { - return *new pxStaticHeading(this, label); + return *new pxStaticHeading(this, label); } void wxDialogWithHelpers::RememberPosition() { - // Save the dialog position if the dialog is named... - // FIXME : This doesn't get called if the app is exited by alt-f4'ing the main app window. - // ... not sure how to fix that yet. I could register a list of open windows into wxAppWithHelpers - // that systematically get closed. Seems like work, maybe later. --air + // Save the dialog position if the dialog is named... + // FIXME : This doesn't get called if the app is exited by alt-f4'ing the main app window. + // ... not sure how to fix that yet. I could register a list of open windows into wxAppWithHelpers + // that systematically get closed. Seems like work, maybe later. --air - if (wxConfigBase *cfg = IsIconized() ? NULL : wxConfigBase::Get(false)) { - const wxString dlgName(GetDialogName()); - const wxRect screenRect(GetScreenRect()); - if (!dlgName.IsEmpty() && (m_CreatedRect != screenRect)) { - wxPoint pos(screenRect.GetPosition()); - IniSaver saver(cfg); - ScopedIniGroup group(saver, L"DialogPositions"); + if (wxConfigBase* cfg = IsIconized() ? NULL : wxConfigBase::Get(false)) + { + const wxString dlgName(GetDialogName()); + const wxRect screenRect(GetScreenRect()); + if (!dlgName.IsEmpty() && (m_CreatedRect != screenRect)) + { + wxPoint pos(screenRect.GetPosition()); + IniSaver saver(cfg); + ScopedIniGroup group(saver, L"DialogPositions"); - if (GetWindowStyle() & wxRESIZE_BORDER) { - wxSize size(screenRect.GetSize()); - saver.Entry(dlgName + L"_Size", size, screenRect.GetSize()); - } - saver.Entry(dlgName + L"_Pos", pos, screenRect.GetPosition()); - } - } + if (GetWindowStyle() & wxRESIZE_BORDER) + { + wxSize size(screenRect.GetSize()); + saver.Entry(dlgName + L"_Size", size, screenRect.GetSize()); + } + saver.Entry(dlgName + L"_Pos", pos, screenRect.GetPosition()); + } + } } -void wxDialogWithHelpers::OnOkCancel(wxCommandEvent &evt) +void wxDialogWithHelpers::OnOkCancel(wxCommandEvent& evt) { - RememberPosition(); + RememberPosition(); - // Modal dialogs should be destroyed after ShowModal returns, otherwise there - // might be double delete problems if the dialog was declared on the stack. - if (!IsModal()) - Destroy(); - else - evt.Skip(); + // Modal dialogs should be destroyed after ShowModal returns, otherwise there + // might be double delete problems if the dialog was declared on the stack. + if (!IsModal()) + Destroy(); + else + evt.Skip(); } -void wxDialogWithHelpers::AddOkCancel(wxSizer &sizer, bool hasApply) +void wxDialogWithHelpers::AddOkCancel(wxSizer& sizer, bool hasApply) { - wxStdDialogButtonSizer &s_buttons(*new wxStdDialogButtonSizer()); + wxStdDialogButtonSizer& s_buttons(*new wxStdDialogButtonSizer()); - s_buttons.AddButton(new wxButton(this, wxID_OK)); - s_buttons.AddButton(new wxButton(this, wxID_CANCEL)); + s_buttons.AddButton(new wxButton(this, wxID_OK)); + s_buttons.AddButton(new wxButton(this, wxID_CANCEL)); - if (hasApply) - s_buttons.AddButton(new wxButton(this, wxID_APPLY)); + if (hasApply) + s_buttons.AddButton(new wxButton(this, wxID_APPLY)); - m_extraButtonSizer = new wxBoxSizer(wxHORIZONTAL); + m_extraButtonSizer = new wxBoxSizer(wxHORIZONTAL); - // Add the context-sensitive help button on the caption for the platforms - // which support it (currently MSW only) - if (m_hasContextHelp) { - SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + // Add the context-sensitive help button on the caption for the platforms + // which support it (currently MSW only) + if (m_hasContextHelp) + { + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); #ifndef __WXMSW__ - *m_extraButtonSizer += new wxContextHelpButton(this) | StdButton(); + *m_extraButtonSizer += new wxContextHelpButton(this) | StdButton(); #endif - } + } - // create a sizer to hold the help and ok/cancel buttons, for platforms - // that need a custom help icon. [fixme: help icon prolly better off somewhere else] - wxFlexGridSizer &flex(*new wxFlexGridSizer(2)); - flex.AddGrowableCol(0, 1); - flex.AddGrowableCol(1, 15); + // create a sizer to hold the help and ok/cancel buttons, for platforms + // that need a custom help icon. [fixme: help icon prolly better off somewhere else] + wxFlexGridSizer& flex(*new wxFlexGridSizer(2)); + flex.AddGrowableCol(0, 1); + flex.AddGrowableCol(1, 15); - flex += m_extraButtonSizer | pxAlignLeft; - flex += s_buttons | (pxExpand & pxCenter); + flex += m_extraButtonSizer | pxAlignLeft; + flex += s_buttons | (pxExpand & pxCenter); - sizer += flex | StdExpand(); + sizer += flex | StdExpand(); - s_buttons.Realize(); + s_buttons.Realize(); } -void wxDialogWithHelpers::AddOkCancel(wxSizer *sizer, bool hasApply) +void wxDialogWithHelpers::AddOkCancel(wxSizer* sizer, bool hasApply) { - if (sizer == NULL) - sizer = GetSizer(); - pxAssert(sizer); - AddOkCancel(*sizer, hasApply); + if (sizer == NULL) + sizer = GetSizer(); + pxAssert(sizer); + AddOkCancel(*sizer, hasApply); } -wxDialogWithHelpers &wxDialogWithHelpers::SetMinWidth(int newWidth) +wxDialogWithHelpers& wxDialogWithHelpers::SetMinWidth(int newWidth) { - SetMinSize(wxSize(newWidth, GetMinHeight())); - if (wxSizer *sizer = GetSizer()) - sizer->SetMinSize(wxSize(newWidth, sizer->GetMinSize().GetHeight())); - return *this; + SetMinSize(wxSize(newWidth, GetMinHeight())); + if (wxSizer* sizer = GetSizer()) + sizer->SetMinSize(wxSize(newWidth, sizer->GetMinSize().GetHeight())); + return *this; } -wxDialogWithHelpers &wxDialogWithHelpers::SetMinHeight(int newHeight) +wxDialogWithHelpers& wxDialogWithHelpers::SetMinHeight(int newHeight) { - SetMinSize(wxSize(GetMinWidth(), newHeight)); - if (wxSizer *sizer = GetSizer()) - sizer->SetMinSize(wxSize(sizer->GetMinSize().GetWidth(), newHeight)); - return *this; + SetMinSize(wxSize(GetMinWidth(), newHeight)); + if (wxSizer* sizer = GetSizer()) + sizer->SetMinSize(wxSize(sizer->GetMinSize().GetWidth(), newHeight)); + return *this; } int wxDialogWithHelpers::GetCharHeight() const { - return pxGetCharHeight(this, 1); + return pxGetCharHeight(this, 1); } // -------------------------------------------------------------------------------------- @@ -377,84 +389,84 @@ void wxPanelWithHelpers::Init() // sizer for this panel. If the panel already has a sizer set, then that sizer will be // transfered to the new StaticBoxSizer (and will be the first item in it's list, retaining // consistent and expected layout) -wxPanelWithHelpers *wxPanelWithHelpers::AddFrame(const wxString &label, wxOrientation orient) +wxPanelWithHelpers* wxPanelWithHelpers::AddFrame(const wxString& label, wxOrientation orient) { - wxSizer *oldSizer = GetSizer(); + wxSizer* oldSizer = GetSizer(); - SetSizer(new wxStaticBoxSizer(orient, this, label), false); - Init(); + SetSizer(new wxStaticBoxSizer(orient, this, label), false); + Init(); - if (oldSizer) - *this += oldSizer | pxExpand; + if (oldSizer) + *this += oldSizer | pxExpand; - return this; + return this; } -wxStaticText &wxPanelWithHelpers::Label(const wxString &label) +wxStaticText& wxPanelWithHelpers::Label(const wxString& label) { - return *new wxStaticText(this, wxID_ANY, label); + return *new wxStaticText(this, wxID_ANY, label); } -pxStaticText &wxPanelWithHelpers::Text(const wxString &label) +pxStaticText& wxPanelWithHelpers::Text(const wxString& label) { - return *new pxStaticText(this, label); + return *new pxStaticText(this, label); } -pxStaticText &wxPanelWithHelpers::Heading(const wxString &label) +pxStaticText& wxPanelWithHelpers::Heading(const wxString& label) { - return *new pxStaticHeading(this, label); + return *new pxStaticHeading(this, label); } -wxPanelWithHelpers::wxPanelWithHelpers(wxWindow *parent, wxOrientation orient, const wxString &staticBoxLabel) - : wxPanel(parent) +wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent, wxOrientation orient, const wxString& staticBoxLabel) + : wxPanel(parent) { - SetSizer(new wxStaticBoxSizer(orient, this, staticBoxLabel)); - Init(); + SetSizer(new wxStaticBoxSizer(orient, this, staticBoxLabel)); + Init(); } -wxPanelWithHelpers::wxPanelWithHelpers(wxWindow *parent, wxOrientation orient) - : wxPanel(parent) +wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent, wxOrientation orient) + : wxPanel(parent) { - SetSizer(new wxBoxSizer(orient)); - Init(); + SetSizer(new wxBoxSizer(orient)); + Init(); } -wxPanelWithHelpers::wxPanelWithHelpers(wxWindow *parent) - : wxPanel(parent) +wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent) + : wxPanel(parent) { - Init(); + Init(); } -wxPanelWithHelpers::wxPanelWithHelpers(wxWindow *parent, const wxPoint &pos, const wxSize &size) - : wxPanel(parent, wxID_ANY, pos, size) +wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent, const wxPoint& pos, const wxSize& size) + : wxPanel(parent, wxID_ANY, pos, size) { - Init(); + Init(); } -wxPanelWithHelpers &wxPanelWithHelpers::SetMinWidth(int newWidth) +wxPanelWithHelpers& wxPanelWithHelpers::SetMinWidth(int newWidth) { - SetMinSize(wxSize(newWidth, GetMinHeight())); - if (wxSizer *sizer = GetSizer()) - sizer->SetMinSize(wxSize(newWidth, sizer->GetMinSize().GetHeight())); - return *this; + SetMinSize(wxSize(newWidth, GetMinHeight())); + if (wxSizer* sizer = GetSizer()) + sizer->SetMinSize(wxSize(newWidth, sizer->GetMinSize().GetHeight())); + return *this; } -int pxGetCharHeight(const wxWindow *wind, int rows) +int pxGetCharHeight(const wxWindow* wind, int rows) { - if (!wind) - return 0; - wxClientDC dc(wx_const_cast(wxWindow *, wind)); - dc.SetFont(wind->GetFont()); + if (!wind) + return 0; + wxClientDC dc(wx_const_cast(wxWindow*, wind)); + dc.SetFont(wind->GetFont()); #ifdef __linux__ - // It seems there is a bad detection of the size of the font (non standard dpi ???). Font are cut in top or bottom. - // Add a correction factor to leave enough room. Visualy 1.7 seems fine but feel free to tune it -- Gregory - return (dc.GetCharHeight() * 1.7 + 1) * rows; + // It seems there is a bad detection of the size of the font (non standard dpi ???). Font are cut in top or bottom. + // Add a correction factor to leave enough room. Visualy 1.7 seems fine but feel free to tune it -- Gregory + return (dc.GetCharHeight() * 1.7 + 1) * rows; #else - return (dc.GetCharHeight() + 1) * rows; + return (dc.GetCharHeight() + 1) * rows; #endif } -int pxGetCharHeight(const wxWindow &wind, int rows) +int pxGetCharHeight(const wxWindow& wind, int rows) { - return pxGetCharHeight(&wind, rows); + return pxGetCharHeight(&wind, rows); }