Merge pull request #428 from Sonicadvance1/x86_32-removal

Remove x86_32 support from Dolphin.
This commit is contained in:
Pierre Bourdon
2014-08-03 21:17:28 -07:00
39 changed files with 42 additions and 1469 deletions
+3 -6
View File
@@ -148,14 +148,11 @@ inline u64 _rotr64(u64 x, unsigned int shift){
#define fstat64 _fstat64
#define fileno _fileno
#if _M_X86_32
#define Crash() {__asm int 3}
#else
extern "C" {
extern "C"
{
__declspec(dllimport) void __stdcall DebugBreak(void);
}
#define Crash() {DebugBreak();}
#endif // M_IX86
#define Crash() {DebugBreak();}
#endif // WIN32 ndef
// Generic function to get last error message.
-12
View File
@@ -152,14 +152,8 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L
_tcscpy( lpszSymbol, _T("?") );
// Get symbol info for IP
#if _M_X86_32
DWORD dwDisp = 0;
if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, &dwDisp, pSym ) )
#else
//makes it compile but hell im not sure if this works...
DWORD64 dwDisp = 0;
if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) )
#endif
{
// Make the symbol readable for humans
UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE,
@@ -313,15 +307,9 @@ void StackTrace( HANDLE hThread, const char* lpszMessage, FILE *file )
}
::ZeroMemory( &callStack, sizeof(callStack) );
#if _M_X86_32
callStack.AddrPC.Offset = context.Eip;
callStack.AddrStack.Offset = context.Esp;
callStack.AddrFrame.Offset = context.Ebp;
#else
callStack.AddrPC.Offset = context.Rip;
callStack.AddrStack.Offset = context.Rsp;
callStack.AddrFrame.Offset = context.Rbp;
#endif
callStack.AddrPC.Mode = AddrModeFlat;
callStack.AddrStack.Mode = AddrModeFlat;
callStack.AddrFrame.Mode = AddrModeFlat;
+5 -39
View File
@@ -40,39 +40,25 @@
#define USE_RVALUE_REFERENCES
#endif
#if defined(_WIN32) && _M_X86_64
#define USE_CONDITION_VARIABLES
#elif defined(_WIN32)
#define USE_EVENTS
#endif
namespace std
{
class condition_variable
{
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
#if defined(_WIN32)
typedef CONDITION_VARIABLE native_type;
#elif defined(_WIN32)
typedef HANDLE native_type;
#else
typedef pthread_cond_t native_type;
#endif
public:
#ifdef USE_EVENTS
typedef native_type native_handle_type;
#else
typedef native_type* native_handle_type;
#endif
condition_variable()
{
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
#if defined(_WIN32)
InitializeConditionVariable(&m_handle);
#elif defined(_WIN32)
m_handle = CreateEvent(nullptr, false, false, nullptr);
#else
pthread_cond_init(&m_handle, nullptr);
#endif
@@ -80,9 +66,7 @@ public:
~condition_variable()
{
#if defined(_WIN32) && !defined(USE_CONDITION_VARIABLES)
CloseHandle(m_handle);
#elif !defined(_WIN32)
#ifndef _WIN32
pthread_cond_destroy(&m_handle);
#endif
}
@@ -92,10 +76,8 @@ public:
void notify_one()
{
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
#if defined(_WIN32)
WakeConditionVariable(&m_handle);
#elif defined(_WIN32)
SetEvent(m_handle);
#else
pthread_cond_signal(&m_handle);
#endif
@@ -103,11 +85,8 @@ public:
void notify_all()
{
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
#if defined(_WIN32)
WakeAllConditionVariable(&m_handle);
#elif defined(_WIN32)
// TODO: broken
SetEvent(m_handle);
#else
pthread_cond_broadcast(&m_handle);
#endif
@@ -116,16 +95,7 @@ public:
void wait(unique_lock<mutex>& lock)
{
#ifdef _WIN32
#ifdef USE_SRWLOCKS
SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0);
#elif defined(USE_CONDITION_VARIABLES)
SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE);
#else
// TODO: broken, the unlock and wait need to be atomic
lock.unlock();
WaitForSingleObject(m_handle, INFINITE);
lock.lock();
#endif
#else
pthread_cond_wait(&m_handle, lock.mutex()->native_handle());
#endif
@@ -158,11 +128,7 @@ public:
native_handle_type native_handle()
{
#ifdef USE_EVENTS
return m_handle;
#else
return &m_handle;
#endif
}
private:
-10
View File
@@ -44,10 +44,6 @@
#define USE_RVALUE_REFERENCES
#endif
#if defined(_WIN32) && _M_X86_64
#define USE_SRWLOCKS
#endif
namespace std
{
@@ -122,7 +118,6 @@ private:
native_type m_handle;
};
#if !defined(_WIN32) || defined(USE_SRWLOCKS)
class mutex
{
@@ -193,11 +188,6 @@ private:
native_type m_handle;
};
#else
typedef recursive_mutex mutex; // just use CriticalSections
#endif
enum defer_lock_t { defer_lock };
enum try_to_lock_t { try_to_lock };
enum adopt_lock_t { adopt_lock };
+1 -1
View File
@@ -2,7 +2,7 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
#if defined(_WIN32) && defined(_M_X86_64)
#if defined(_WIN32)
#include <math.h>
#include <Windows.h>
+4 -190
View File
@@ -11,26 +11,7 @@ using namespace Gen;
// Shared code between Win64 and Unix64
unsigned int XEmitter::ABI_GetAlignedFrameSize(unsigned int frameSize, bool noProlog) {
// On platforms other than Windows 32-bit: At the beginning of a function,
// the stack pointer is 4/8 bytes less than a multiple of 16; however, the
// function prolog immediately subtracts an appropriate amount to align
// it, so no alignment is required around a call.
// In the functions generated by ThunkManager::ProtectFunction and some
// others, we add the necessary subtraction (and 0x20 bytes shadow space
// for Win64) into this rather than having a separate prolog.
// On Windows 32-bit, the required alignment is only 4 bytes, so we just
// ensure that the frame size isn't misaligned.
#if _M_X86_64
// expect frameSize == 0
frameSize = noProlog ? 0x28 : 0;
#elif defined(_WIN32)
frameSize = (frameSize + 3) & -4;
#else
unsigned int existingAlignment = noProlog ? 0xc : 0;
frameSize -= existingAlignment;
frameSize = (frameSize + 15) & -16;
frameSize += existingAlignment;
#endif
return frameSize;
}
@@ -38,35 +19,22 @@ void XEmitter::ABI_AlignStack(unsigned int frameSize, bool noProlog) {
unsigned int fillSize =
ABI_GetAlignedFrameSize(frameSize, noProlog) - frameSize;
if (fillSize != 0) {
#if _M_X86_64
SUB(64, R(RSP), Imm8(fillSize));
#else
SUB(32, R(ESP), Imm8(fillSize));
#endif
}
}
void XEmitter::ABI_RestoreStack(unsigned int frameSize, bool noProlog) {
unsigned int alignedSize = ABI_GetAlignedFrameSize(frameSize, noProlog);
if (alignedSize != 0) {
#if _M_X86_64
ADD(64, R(RSP), Imm8(alignedSize));
#else
ADD(32, R(ESP), Imm8(alignedSize));
#endif
}
}
void XEmitter::ABI_PushRegistersAndAdjustStack(u32 mask, bool noProlog)
{
int regSize =
#if _M_X86_64
8;
#else
4;
#endif
int regSize = 8;
int shadow = 0;
#if defined(_WIN32) && _M_X86_64
#if defined(_WIN32)
shadow = 0x20;
#endif
int count = 0;
@@ -100,14 +68,9 @@ void XEmitter::ABI_PushRegistersAndAdjustStack(u32 mask, bool noProlog)
void XEmitter::ABI_PopRegistersAndAdjustStack(u32 mask, bool noProlog)
{
int regSize =
#if _M_X86_64
8;
#else
4;
#endif
int regSize = 8;
int size = 0;
#if defined(_WIN32) && _M_X86_64
#if defined(_WIN32)
size += 0x20;
#endif
for (int x = 0; x < 16; x++)
@@ -137,152 +100,6 @@ void XEmitter::ABI_PopRegistersAndAdjustStack(u32 mask, bool noProlog)
}
}
#if _M_X86_32 // All32
// Shared code between Win32 and Unix32
void XEmitter::ABI_CallFunction(void *func) {
ABI_AlignStack(0);
CALL(func);
ABI_RestoreStack(0);
}
void XEmitter::ABI_CallFunctionC16(void *func, u16 param1) {
ABI_AlignStack(1 * 2);
PUSH(16, Imm16(param1));
CALL(func);
ABI_RestoreStack(1 * 2);
}
void XEmitter::ABI_CallFunctionCC16(void *func, u32 param1, u16 param2) {
ABI_AlignStack(1 * 2 + 1 * 4);
PUSH(16, Imm16(param2));
PUSH(32, Imm32(param1));
CALL(func);
ABI_RestoreStack(1 * 2 + 1 * 4);
}
void XEmitter::ABI_CallFunctionC(void *func, u32 param1) {
ABI_AlignStack(1 * 4);
PUSH(32, Imm32(param1));
CALL(func);
ABI_RestoreStack(1 * 4);
}
void XEmitter::ABI_CallFunctionCC(void *func, u32 param1, u32 param2) {
ABI_AlignStack(2 * 4);
PUSH(32, Imm32(param2));
PUSH(32, Imm32(param1));
CALL(func);
ABI_RestoreStack(2 * 4);
}
void XEmitter::ABI_CallFunctionCP(void *func, u32 param1, void *param2) {
ABI_AlignStack(2 * 4);
PUSH(32, Imm32((u32)param2));
PUSH(32, Imm32(param1));
CALL(func);
ABI_RestoreStack(2 * 4);
}
void XEmitter::ABI_CallFunctionCCC(void *func, u32 param1, u32 param2, u32 param3) {
ABI_AlignStack(3 * 4);
PUSH(32, Imm32(param3));
PUSH(32, Imm32(param2));
PUSH(32, Imm32(param1));
CALL(func);
ABI_RestoreStack(3 * 4);
}
void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *param3) {
ABI_AlignStack(3 * 4);
PUSH(32, Imm32((u32)param3));
PUSH(32, Imm32(param2));
PUSH(32, Imm32(param1));
CALL(func);
ABI_RestoreStack(3 * 4);
}
void XEmitter::ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2,u32 param3, void *param4) {
ABI_AlignStack(4 * 4);
PUSH(32, Imm32((u32)param4));
PUSH(32, Imm32(param3));
PUSH(32, Imm32(param2));
PUSH(32, Imm32(param1));
CALL(func);
ABI_RestoreStack(4 * 4);
}
void XEmitter::ABI_CallFunctionPC(void *func, void *param1, u32 param2) {
ABI_AlignStack(2 * 4);
PUSH(32, Imm32(param2));
PUSH(32, Imm32((u32)param1));
CALL(func);
ABI_RestoreStack(2 * 4);
}
void XEmitter::ABI_CallFunctionPPC(void *func, void *param1, void *param2,u32 param3) {
ABI_AlignStack(3 * 4);
PUSH(32, Imm32(param3));
PUSH(32, Imm32((u32)param2));
PUSH(32, Imm32((u32)param1));
CALL(func);
ABI_RestoreStack(3 * 4);
}
// Pass a register as a parameter.
void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) {
ABI_AlignStack(1 * 4);
PUSH(32, R(reg1));
CALL(func);
ABI_RestoreStack(1 * 4);
}
// Pass two registers as parameters.
void XEmitter::ABI_CallFunctionRR(void *func, Gen::X64Reg reg1, Gen::X64Reg reg2, bool noProlog)
{
ABI_AlignStack(2 * 4, noProlog);
PUSH(32, R(reg2));
PUSH(32, R(reg1));
CALL(func);
ABI_RestoreStack(2 * 4, noProlog);
}
void XEmitter::ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2)
{
ABI_AlignStack(2 * 4);
PUSH(32, Imm32(param2));
PUSH(32, arg1);
CALL(func);
ABI_RestoreStack(2 * 4);
}
void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1)
{
ABI_AlignStack(1 * 4);
PUSH(32, arg1);
CALL(func);
ABI_RestoreStack(1 * 4);
}
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
PUSH(EBP);
MOV(32, R(EBP), R(ESP));
PUSH(EBX);
PUSH(ESI);
PUSH(EDI);
SUB(32, R(ESP), Imm8(0xc));
}
void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() {
ADD(32, R(ESP), Imm8(0xc));
POP(EDI);
POP(ESI);
POP(EBX);
POP(EBP);
}
#else //64bit
// Common functions
void XEmitter::ABI_CallFunction(void *func) {
ABI_AlignStack(0);
@@ -643,6 +460,3 @@ void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() {
#endif // WIN32
#endif // 32bit
+1 -26
View File
@@ -6,17 +6,9 @@
#include "Common/x64Emitter.h"
// x86/x64 ABI:s, and helpers to help follow them when JIT-ing code.
// x64 ABI:s, and helpers to help follow them when JIT-ing code.
// All convensions return values in EAX (+ possibly EDX).
// Linux 32-bit, Windows 32-bit (cdecl, System V):
// * Caller pushes left to right
// * Caller fixes stack after call
// * function subtract from stack for local storage only.
// Scratch: EAX ECX EDX
// Callee-save: EBX ESI EDI EBP
// Parameters: -
// Windows 64-bit
// * 4-reg "fastcall" variant, very new-skool stack handling
// * Callee moves stack pointer, to make room for shadow regs for the biggest function _it itself calls_
@@ -31,22 +23,6 @@
// Callee-save: RBX RBP R12 R13 R14 R15
// Parameters: RDI RSI RDX RCX R8 R9
#if _M_X86_32 // 32 bit calling convention, shared by all
// 32-bit don't pass parameters in regs, but these are convenient to have anyway when we have to
// choose regs to put stuff in.
#define ABI_PARAM1 RCX
#define ABI_PARAM2 RDX
// There are no ABI_PARAM* here, since args are pushed.
// 32-bit bog standard cdecl, shared between linux and windows
// MacOSX 32-bit is same as System V with a few exceptions that we probably don't care much about.
#define ABI_ALL_CALLEE_SAVED ((1 << EAX) | (1 << ECX) | (1 << EDX) | \
0xff00 /* xmm0..7 */)
#else // 64 bit calling convention
#ifdef _WIN32 // 64-bit Windows - the really exotic calling convention
#define ABI_PARAM1 RCX
@@ -74,4 +50,3 @@
#endif // WIN32
#endif // X86
+1 -11
View File
@@ -90,22 +90,12 @@ CPUInfo::CPUInfo() {
void CPUInfo::Detect()
{
memset(this, 0, sizeof(*this));
#if _M_X86_32
Mode64bit = false;
#elif _M_X86_64
#ifdef _M_X86_64
Mode64bit = true;
OS64bit = true;
#endif
num_cores = 1;
#ifdef _WIN32
#if _M_X86_32
BOOL f64 = false;
IsWow64Process(GetCurrentProcess(), &f64);
OS64bit = (f64 == TRUE) ? true : false;
#endif
#endif
// Set obvious defaults, for extra safety
if (Mode64bit) {
bSSE = true;
-94
View File
@@ -125,7 +125,6 @@ void XEmitter::WriteSIB(int scale, int index, int base)
void OpArg::WriteRex(XEmitter *emit, int opBits, int bits, int customOp) const
{
if (customOp == -1) customOp = operandReg;
#if _M_X86_64
u8 op = 0x40;
// REX.W (whether operation is a 64-bit operation)
if (opBits == 64) op |= 8;
@@ -145,17 +144,6 @@ void OpArg::WriteRex(XEmitter *emit, int opBits, int bits, int customOp) const
_dbg_assert_(DYNA_REC, (offsetOrBaseReg & 0x100) == 0);
_dbg_assert_(DYNA_REC, (customOp & 0x100) == 0);
}
#else
// Make sure we don't perform a 64-bit operation.
_dbg_assert_(DYNA_REC, opBits != 64);
// Make sure the operation doesn't access R8-R15 registers.
_dbg_assert_(DYNA_REC, (customOp & 8) == 0);
_dbg_assert_(DYNA_REC, (indexReg & 8) == 0);
_dbg_assert_(DYNA_REC, (offsetOrBaseReg & 8) == 0);
// Make sure the operation doesn't access SIL, DIL, BPL, or SPL.
_dbg_assert_(DYNA_REC, opBits != 8 || (customOp & 0x10c) != 4);
_dbg_assert_(DYNA_REC, scale != SCALE_NONE || bits != 8 || (offsetOrBaseReg & 0x10c) != 4);
#endif
}
void OpArg::WriteVex(XEmitter* emit, int size, int packed, Gen::X64Reg regOp1, Gen::X64Reg regOp2) const
@@ -208,7 +196,6 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg,
_offsetOrBaseReg = 5;
emit->WriteModRM(0, _operandReg, _offsetOrBaseReg);
//TODO : add some checks
#if _M_X86_64
u64 ripAddr = (u64)emit->GetCodePtr() + 4 + extraBytes;
s64 distance = (s64)offset - (s64)ripAddr;
_assert_msg_(DYNA_REC,
@@ -219,9 +206,6 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg,
ripAddr, offset);
s32 offs = (s32)distance;
emit->Write32((u32)offs);
#else
emit->Write32((u32)offset);
#endif
return;
}
@@ -1267,7 +1251,6 @@ void XEmitter::MOVD_xmm(X64Reg dest, const OpArg &arg) {WriteSSEOp(64, 0x6E, tru
void XEmitter::MOVD_xmm(const OpArg &arg, X64Reg src) {WriteSSEOp(64, 0x7E, true, src, arg, 0);}
void XEmitter::MOVQ_xmm(X64Reg dest, OpArg arg) {
#if _M_X86_64
// Alternate encoding
// This does not display correctly in MSVC's debugger, it thinks it's a MOVD
arg.operandReg = dest;
@@ -1276,13 +1259,6 @@ void XEmitter::MOVQ_xmm(X64Reg dest, OpArg arg) {
Write8(0x0f);
Write8(0x6E);
arg.WriteRest(this, 0);
#else
arg.operandReg = dest;
Write8(0xF3);
Write8(0x0f);
Write8(0x7E);
arg.WriteRest(this, 0);
#endif
}
void XEmitter::MOVQ_xmm(OpArg arg, X64Reg src) {
@@ -1626,8 +1602,6 @@ void XEmitter::RTDSC() { Write8(0x0F); Write8(0x31); }
void XEmitter::CallCdeclFunction3(void* fnptr, u32 arg0, u32 arg1, u32 arg2)
{
using namespace Gen;
#if _M_X86_64
#ifdef _MSC_VER
MOV(32, R(RCX), Imm32(arg0));
MOV(32, R(RDX), Imm32(arg1));
@@ -1639,26 +1613,11 @@ void XEmitter::CallCdeclFunction3(void* fnptr, u32 arg0, u32 arg1, u32 arg2)
MOV(32, R(RDX), Imm32(arg2));
CALL(fnptr);
#endif
#else
ABI_AlignStack(3 * 4);
PUSH(32, Imm32(arg2));
PUSH(32, Imm32(arg1));
PUSH(32, Imm32(arg0));
CALL(fnptr);
#ifdef _WIN32
// don't inc stack
#else
ABI_RestoreStack(3 * 4);
#endif
#endif
}
void XEmitter::CallCdeclFunction4(void* fnptr, u32 arg0, u32 arg1, u32 arg2, u32 arg3)
{
using namespace Gen;
#if _M_X86_64
#ifdef _MSC_VER
MOV(32, R(RCX), Imm32(arg0));
MOV(32, R(RDX), Imm32(arg1));
@@ -1672,27 +1631,11 @@ void XEmitter::CallCdeclFunction4(void* fnptr, u32 arg0, u32 arg1, u32 arg2, u32
MOV(32, R(RCX), Imm32(arg3));
CALL(fnptr);
#endif
#else
ABI_AlignStack(4 * 4);
PUSH(32, Imm32(arg3));
PUSH(32, Imm32(arg2));
PUSH(32, Imm32(arg1));
PUSH(32, Imm32(arg0));
CALL(fnptr);
#ifdef _WIN32
// don't inc stack
#else
ABI_RestoreStack(4 * 4);
#endif
#endif
}
void XEmitter::CallCdeclFunction5(void* fnptr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
{
using namespace Gen;
#if _M_X86_64
#ifdef _MSC_VER
MOV(32, R(RCX), Imm32(arg0));
MOV(32, R(RDX), Imm32(arg1));
@@ -1708,28 +1651,11 @@ void XEmitter::CallCdeclFunction5(void* fnptr, u32 arg0, u32 arg1, u32 arg2, u32
MOV(32, R(R8), Imm32(arg4));
CALL(fnptr);
#endif
#else
ABI_AlignStack(5 * 4);
PUSH(32, Imm32(arg4));
PUSH(32, Imm32(arg3));
PUSH(32, Imm32(arg2));
PUSH(32, Imm32(arg1));
PUSH(32, Imm32(arg0));
CALL(fnptr);
#ifdef _WIN32
// don't inc stack
#else
ABI_RestoreStack(5 * 4);
#endif
#endif
}
void XEmitter::CallCdeclFunction6(void* fnptr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
{
using namespace Gen;
#if _M_X86_64
#ifdef _MSC_VER
MOV(32, R(RCX), Imm32(arg0));
MOV(32, R(RDX), Imm32(arg1));
@@ -1747,26 +1673,8 @@ void XEmitter::CallCdeclFunction6(void* fnptr, u32 arg0, u32 arg1, u32 arg2, u32
MOV(32, R(R9), Imm32(arg5));
CALL(fnptr);
#endif
#else
ABI_AlignStack(6 * 4);
PUSH(32, Imm32(arg5));
PUSH(32, Imm32(arg4));
PUSH(32, Imm32(arg3));
PUSH(32, Imm32(arg2));
PUSH(32, Imm32(arg1));
PUSH(32, Imm32(arg0));
CALL(fnptr);
#ifdef _WIN32
// don't inc stack
#else
ABI_RestoreStack(6 * 4);
#endif
#endif
}
#if _M_X86_64
// See header
void XEmitter::___CallCdeclImport3(void* impptr, u32 arg0, u32 arg1, u32 arg2) {
MOV(32, R(RCX), Imm32(arg0));
@@ -1799,6 +1707,4 @@ void XEmitter::___CallCdeclImport6(void* impptr, u32 arg0, u32 arg1, u32 arg2, u
CALLptr(M(impptr));
}
#endif
}
-17
View File
@@ -702,11 +702,7 @@ public:
void ABI_AlignStack(unsigned int frameSize, bool noProlog = false);
void ABI_RestoreStack(unsigned int frameSize, bool noProlog = false);
#if _M_X86_32
inline int ABI_GetNumXMMRegs() { return 8; }
#else
inline int ABI_GetNumXMMRegs() { return 16; }
#endif
// Strange call wrappers.
void CallCdeclFunction3(void* fnptr, u32 arg0, u32 arg1, u32 arg2);
@@ -714,17 +710,6 @@ public:
void CallCdeclFunction5(void* fnptr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
void CallCdeclFunction6(void* fnptr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4, u32 arg5);
#if _M_X86_32
#define CallCdeclFunction3_I(a,b,c,d) CallCdeclFunction3((void *)(a), (b), (c), (d))
#define CallCdeclFunction4_I(a,b,c,d,e) CallCdeclFunction4((void *)(a), (b), (c), (d), (e))
#define CallCdeclFunction5_I(a,b,c,d,e,f) CallCdeclFunction5((void *)(a), (b), (c), (d), (e), (f))
#define CallCdeclFunction6_I(a,b,c,d,e,f,g) CallCdeclFunction6((void *)(a), (b), (c), (d), (e), (f), (g))
#define DECLARE_IMPORT(x)
#else
// Comments from VertexLoader.cpp about these horrors:
// This is a horrible hack that is necessary in 64-bit mode because Opengl32.dll is based way, way above the 32-bit
@@ -743,8 +728,6 @@ public:
#define DECLARE_IMPORT(x) extern "C" void *__imp_##x
#endif
// Utility to generate a call to a std::function object.
//
// Unfortunately, calling operator() directly is undefined behavior in C++
+2 -23
View File
@@ -32,30 +32,9 @@ namespace FPURoundMode
fesetround(rounding_mode_lut[mode]);
}
void SetPrecisionMode(PrecisionMode mode)
void SetPrecisionMode(PrecisionMode /* mode */)
{
#ifdef _M_X86_32
// sets the floating-point lib to 53-bit
// PowerPC has a 53bit floating pipeline only
// eg: sscanf is very sensitive
#ifdef _WIN32
_control87(_PC_53, MCW_PC);
#else
const unsigned short PRECISION_MASK = 3 << 8;
const unsigned short precision_table[] = {
0 << 8, // 24 bits
2 << 8, // 53 bits
3 << 8, // 64 bits
};
unsigned short _mode;
asm ("fstcw %0" : "=m" (_mode));
_mode = (_mode & ~PRECISION_MASK) | precision_table[mode];
asm ("fldcw %0" : : "m" (_mode));
#endif
#else
//x64 doesn't need this - fpu is done with SSE
//but still - set any useful sse options here
#endif
//x64 doesn't need this - fpu is done with SSE
}
void SetSIMDMode(int rounding_mode, bool non_ieee_mode)
+1 -7
View File
@@ -401,15 +401,9 @@ void DSPEmitter::CompileDispatcher()
// Execute block. Cycles executed returned in EAX.
#if _M_X86_32
MOVZX(32, 16, ECX, M(&g_dsp.pc));
MOV(32, R(EBX), ImmPtr(blocks));
JMPptr(MComplex(EBX, ECX, SCALE_4, 0));
#else
MOVZX(64, 16, ECX, M(&g_dsp.pc));//for clarity, use 64 here.
MOVZX(64, 16, ECX, M(&g_dsp.pc));
MOV(64, R(RBX), ImmPtr(blocks));
JMPptr(MComplex(RBX, RCX, SCALE_8, 0));
#endif
returnDispatcher = GetCodePtr();
File diff suppressed because it is too large Load Diff
-12
View File
@@ -13,7 +13,6 @@ using namespace Gen;
// Clobbers RDX
void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
{
#if _M_X86_64
OpArg sr_reg;
gpr.getReg(DSP_REG_SR,sr_reg);
// // 0x04
@@ -50,21 +49,18 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
OR(16, sr_reg, Imm16(SR_TOP2BITS));
SetJumpTarget(cC);
gpr.putReg(DSP_REG_SR);
#endif
}
// In: RAX: s64 _Value
// Clobbers RDX
void DSPEmitter::Update_SR_Register64(Gen::X64Reg val)
{
#if _M_X86_64
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
OpArg sr_reg;
gpr.getReg(DSP_REG_SR,sr_reg);
AND(16, sr_reg, Imm16(~SR_CMP_MASK));
gpr.putReg(DSP_REG_SR);
Update_SR_Register(val);
#endif
}
// In: (val): s64 _Value
@@ -72,7 +68,6 @@ void DSPEmitter::Update_SR_Register64(Gen::X64Reg val)
// Clobbers RDX
void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl)
{
#if _M_X86_64
OpArg sr_reg;
gpr.getReg(DSP_REG_SR,sr_reg);
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
@@ -101,7 +96,6 @@ void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl)
gpr.putReg(DSP_REG_SR);
Update_SR_Register(val);
#endif
}
// In: (val): s64 _Value
@@ -109,7 +103,6 @@ void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl)
// Clobbers RDX
void DSPEmitter::Update_SR_Register64_Carry2(X64Reg val, X64Reg carry_ovfl)
{
#if _M_X86_64
OpArg sr_reg;
gpr.getReg(DSP_REG_SR,sr_reg);
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
@@ -138,7 +131,6 @@ void DSPEmitter::Update_SR_Register64_Carry2(X64Reg val, X64Reg carry_ovfl)
gpr.putReg(DSP_REG_SR);
Update_SR_Register();
#endif
}
//void DSPEmitter::Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool overS32)
@@ -155,7 +147,6 @@ void DSPEmitter::Update_SR_Register64_Carry2(X64Reg val, X64Reg carry_ovfl)
// Clobbers RDX
void DSPEmitter::Update_SR_Register16(X64Reg val)
{
#if _M_X86_64
OpArg sr_reg;
gpr.getReg(DSP_REG_SR,sr_reg);
AND(16, sr_reg, Imm16(~SR_CMP_MASK));
@@ -190,14 +181,12 @@ void DSPEmitter::Update_SR_Register16(X64Reg val)
SetJumpTarget(notThree);
SetJumpTarget(cC);
gpr.putReg(DSP_REG_SR);
#endif
}
// In: RAX: s64 _Value
// Clobbers RDX
void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
{
#if _M_X86_64
OpArg sr_reg;
gpr.getReg(DSP_REG_SR,sr_reg);
AND(16, sr_reg, Imm16(~SR_CMP_MASK));
@@ -215,7 +204,6 @@ void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
//AND(32, R(val), Imm32(0xc0000000));
Update_SR_Register16(val);
#endif
}
//void DSPEmitter::Update_SR_LZ(bool value) {
@@ -17,7 +17,6 @@ using namespace Gen;
// In: RCX = s16 a, RAX = s16 b
void DSPEmitter::multiply()
{
#if _M_X86_64
// prod = (s16)a * (s16)b; //signed
IMUL(64, R(ECX));
@@ -32,35 +31,30 @@ void DSPEmitter::multiply()
SetJumpTarget(noMult2);
gpr.putReg(DSP_REG_SR, false);
// return prod;
#endif
}
// Returns s64 in RAX
// Clobbers RDX
void DSPEmitter::multiply_add()
{
#if _M_X86_64
// s64 prod = dsp_get_long_prod() + dsp_get_multiply_prod(a, b, sign);
multiply();
MOV(64, R(RDX), R(RAX));
get_long_prod();
ADD(64, R(RAX), R(RDX));
// return prod;
#endif
}
// Returns s64 in RAX
// Clobbers RDX
void DSPEmitter::multiply_sub()
{
#if _M_X86_64
// s64 prod = dsp_get_long_prod() - dsp_get_multiply_prod(a, b, sign);
multiply();
MOV(64, R(RDX), R(RAX));
get_long_prod();
SUB(64, R(RAX), R(RDX));
// return prod;
#endif
}
// Only MULX family instructions have unsigned/mixed support.
@@ -69,7 +63,6 @@ void DSPEmitter::multiply_sub()
// Returns s64 in RAX
void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
{
#if _M_X86_64
// s64 result;
// if ((axh0==0) && (axh1==0))
@@ -141,7 +134,6 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
SetJumpTarget(noMult2);
gpr.putReg(DSP_REG_SR, false);
// return prod;
#endif
}
//----
@@ -169,7 +161,6 @@ void DSPEmitter::clrp(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::tstprod(const UDSPInstruction opc)
{
#if _M_X86_64
if (FlagsNeeded())
{
// s64 prod = dsp_get_long_prod();
@@ -177,9 +168,6 @@ void DSPEmitter::tstprod(const UDSPInstruction opc)
// Update_SR_Register64(prod);
Update_SR_Register64();
}
#else
Default(opc);
#endif
}
//----
@@ -191,7 +179,6 @@ void DSPEmitter::tstprod(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::movp(const UDSPInstruction opc)
{
#if _M_X86_64
u8 dreg = (opc >> 8) & 0x1;
// s64 acc = dsp_get_long_prod();
@@ -203,9 +190,6 @@ void DSPEmitter::movp(const UDSPInstruction opc)
{
Update_SR_Register64();
}
#else
Default(opc);
#endif
}
// MOVNP $acD
@@ -216,7 +200,6 @@ void DSPEmitter::movp(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::movnp(const UDSPInstruction opc)
{
#if _M_X86_64
u8 dreg = (opc >> 8) & 0x1;
// s64 acc = -dsp_get_long_prod();
@@ -229,9 +212,6 @@ void DSPEmitter::movnp(const UDSPInstruction opc)
{
Update_SR_Register64();
}
#else
Default(opc);
#endif
}
// MOVPZ $acD
@@ -242,7 +222,6 @@ void DSPEmitter::movnp(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::movpz(const UDSPInstruction opc)
{
#if _M_X86_64
u8 dreg = (opc >> 8) & 0x01;
// s64 acc = dsp_get_long_prod_round_prodl();
@@ -254,9 +233,6 @@ void DSPEmitter::movpz(const UDSPInstruction opc)
{
Update_SR_Register64();
}
#else
Default(opc);
#endif
}
// ADDPAXZ $acD, $axS
@@ -267,7 +243,6 @@ void DSPEmitter::movpz(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::addpaxz(const UDSPInstruction opc)
{
#if _M_X86_64
u8 dreg = (opc >> 8) & 0x1;
u8 sreg = (opc >> 9) & 0x1;
@@ -299,9 +274,6 @@ void DSPEmitter::addpaxz(const UDSPInstruction opc)
set_long_acc(dreg, RAX);
}
gpr.putXReg(tmp1);
#else
Default(opc);
#endif
}
//----
@@ -311,16 +283,12 @@ void DSPEmitter::addpaxz(const UDSPInstruction opc)
// Multiply $ax0.h by $ax0.h
void DSPEmitter::mulaxh(const UDSPInstruction opc)
{
#if _M_X86_64
// s64 prod = dsp_multiply(dsp_get_ax_h(0), dsp_get_ax_h(0));
dsp_op_read_reg(DSP_REG_AXH0, RCX, SIGN);
MOV(64, R(RAX), R(RCX));
multiply();
// dsp_set_long_prod(prod);
set_long_prod();
#else
Default(opc);
#endif
}
//----
@@ -331,7 +299,6 @@ void DSPEmitter::mulaxh(const UDSPInstruction opc)
// $axS.h of secondary accumulator $axS (treat them both as signed).
void DSPEmitter::mul(const UDSPInstruction opc)
{
#if _M_X86_64
u8 sreg = (opc >> 11) & 0x1;
// u16 axl = dsp_get_ax_l(sreg);
@@ -342,9 +309,6 @@ void DSPEmitter::mul(const UDSPInstruction opc)
multiply();
// dsp_set_long_prod(prod);
set_long_prod();
#else
Default(opc);
#endif
}
// MULAC $axS.l, $axS.h, $acR
@@ -356,7 +320,6 @@ void DSPEmitter::mul(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::mulac(const UDSPInstruction opc)
{
#if _M_X86_64
u8 rreg = (opc >> 8) & 0x1;
u8 sreg = (opc >> 11) & 0x1;
@@ -382,9 +345,6 @@ void DSPEmitter::mulac(const UDSPInstruction opc)
{
Update_SR_Register64();
}
#else
Default(opc);
#endif
}
// MULMV $axS.l, $axS.h, $acR
@@ -396,7 +356,6 @@ void DSPEmitter::mulac(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::mulmv(const UDSPInstruction opc)
{
#if _M_X86_64
u8 rreg = (opc >> 8) & 0x1;
// s64 acc = dsp_get_long_prod();
@@ -411,9 +370,6 @@ void DSPEmitter::mulmv(const UDSPInstruction opc)
{
Update_SR_Register64();
}
#else
Default(opc);
#endif
}
// MULMVZ $axS.l, $axS.h, $acR
@@ -426,7 +382,6 @@ void DSPEmitter::mulmv(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::mulmvz(const UDSPInstruction opc)
{
#if _M_X86_64
u8 rreg = (opc >> 8) & 0x1;
// s64 acc = dsp_get_long_prod_round_prodl();
@@ -439,9 +394,6 @@ void DSPEmitter::mulmvz(const UDSPInstruction opc)
{
Update_SR_Register64(RDX);
}
#else
Default(opc);
#endif
}
//----
@@ -452,7 +404,6 @@ void DSPEmitter::mulmvz(const UDSPInstruction opc)
// Part is selected by S and T bits. Zero selects low part, one selects high part.
void DSPEmitter::mulx(const UDSPInstruction opc)
{
#if _M_X86_64
u8 treg = ((opc >> 11) & 0x1);
u8 sreg = ((opc >> 12) & 0x1);
@@ -464,9 +415,6 @@ void DSPEmitter::mulx(const UDSPInstruction opc)
multiply_mulx(sreg, treg);
// dsp_set_long_prod(prod);
set_long_prod();
#else
Default(opc);
#endif
}
// MULXAC $ax0.S, $ax1.T, $acR
@@ -478,7 +426,6 @@ void DSPEmitter::mulx(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::mulxac(const UDSPInstruction opc)
{
#if _M_X86_64
u8 rreg = (opc >> 8) & 0x1;
u8 treg = (opc >> 11) & 0x1;
u8 sreg = (opc >> 12) & 0x1;
@@ -506,9 +453,6 @@ void DSPEmitter::mulxac(const UDSPInstruction opc)
Update_SR_Register64(tmp1);
}
gpr.putXReg(tmp1);
#else
Default(opc);
#endif
}
// MULXMV $ax0.S, $ax1.T, $acR
@@ -520,7 +464,6 @@ void DSPEmitter::mulxac(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::mulxmv(const UDSPInstruction opc)
{
#if _M_X86_64
u8 rreg = ((opc >> 8) & 0x1);
u8 treg = (opc >> 11) & 0x1;
u8 sreg = (opc >> 12) & 0x1;
@@ -546,9 +489,6 @@ void DSPEmitter::mulxmv(const UDSPInstruction opc)
Update_SR_Register64(tmp1);
}
gpr.putXReg(tmp1);
#else
Default(opc);
#endif
}
// MULXMV $ax0.S, $ax1.T, $acR
@@ -561,7 +501,6 @@ void DSPEmitter::mulxmv(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::mulxmvz(const UDSPInstruction opc)
{
#if _M_X86_64
u8 rreg = (opc >> 8) & 0x1;
u8 treg = (opc >> 11) & 0x1;
u8 sreg = (opc >> 12) & 0x1;
@@ -587,9 +526,6 @@ void DSPEmitter::mulxmvz(const UDSPInstruction opc)
Update_SR_Register64(tmp1);
}
gpr.putXReg(tmp1);
#else
Default(opc);
#endif
}
//----
@@ -600,7 +536,6 @@ void DSPEmitter::mulxmvz(const UDSPInstruction opc)
// secondary accumulator $axS (treat them both as signed).
void DSPEmitter::mulc(const UDSPInstruction opc)
{
#if _M_X86_64
u8 treg = (opc >> 11) & 0x1;
u8 sreg = (opc >> 12) & 0x1;
@@ -612,9 +547,6 @@ void DSPEmitter::mulc(const UDSPInstruction opc)
multiply();
// dsp_set_long_prod(prod);
set_long_prod();
#else
Default(opc);
#endif
}
// MULCAC $acS.m, $axT.h, $acR
@@ -626,7 +558,6 @@ void DSPEmitter::mulc(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::mulcac(const UDSPInstruction opc)
{
#if _M_X86_64
u8 rreg = (opc >> 8) & 0x1;
u8 treg = (opc >> 11) & 0x1;
u8 sreg = (opc >> 12) & 0x1;
@@ -653,9 +584,6 @@ void DSPEmitter::mulcac(const UDSPInstruction opc)
{
Update_SR_Register64();
}
#else
Default(opc);
#endif
}
// MULCMV $acS.m, $axT.h, $acR
@@ -668,7 +596,6 @@ void DSPEmitter::mulcac(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::mulcmv(const UDSPInstruction opc)
{
#if _M_X86_64
u8 rreg = (opc >> 8) & 0x1;
u8 treg = (opc >> 11) & 0x1;
u8 sreg = (opc >> 12) & 0x1;
@@ -692,9 +619,6 @@ void DSPEmitter::mulcmv(const UDSPInstruction opc)
{
Update_SR_Register64();
}
#else
Default(opc);
#endif
}
// MULCMVZ $acS.m, $axT.h, $acR
@@ -708,7 +632,6 @@ void DSPEmitter::mulcmv(const UDSPInstruction opc)
// flags out: --xx xx0x
void DSPEmitter::mulcmvz(const UDSPInstruction opc)
{
#if _M_X86_64
u8 rreg = (opc >> 8) & 0x1;
u8 treg = (opc >> 11) & 0x1;
u8 sreg = (opc >> 12) & 0x1;
@@ -732,9 +655,6 @@ void DSPEmitter::mulcmvz(const UDSPInstruction opc)
{
Update_SR_Register64();
}
#else
Default(opc);
#endif
}
//----
@@ -746,7 +666,6 @@ void DSPEmitter::mulcmvz(const UDSPInstruction opc)
// signed) and add result to product register.
void DSPEmitter::maddx(const UDSPInstruction opc)
{
#if _M_X86_64
u8 treg = (opc >> 8) & 0x1;
u8 sreg = (opc >> 9) & 0x1;
@@ -758,9 +677,6 @@ void DSPEmitter::maddx(const UDSPInstruction opc)
multiply_add();
// dsp_set_long_prod(prod);
set_long_prod();
#else
Default(opc);
#endif
}
// MSUBX $(0x18+S*2), $(0x19+T*2)
@@ -770,7 +686,6 @@ void DSPEmitter::maddx(const UDSPInstruction opc)
// signed) and subtract result from product register.
void DSPEmitter::msubx(const UDSPInstruction opc)
{
#if _M_X86_64
u8 treg = (opc >> 8) & 0x1;
u8 sreg = (opc >> 9) & 0x1;
@@ -782,9 +697,6 @@ void DSPEmitter::msubx(const UDSPInstruction opc)
multiply_sub();
// dsp_set_long_prod(prod);
set_long_prod();
#else
Default(opc);
#endif
}
// MADDC $acS.m, $axT.h
@@ -794,7 +706,6 @@ void DSPEmitter::msubx(const UDSPInstruction opc)
// register.
void DSPEmitter::maddc(const UDSPInstruction opc)
{
#if _M_X86_64
u8 treg = (opc >> 8) & 0x1;
u8 sreg = (opc >> 9) & 0x1;
@@ -806,9 +717,6 @@ void DSPEmitter::maddc(const UDSPInstruction opc)
multiply_add();
// dsp_set_long_prod(prod);
set_long_prod();
#else
Default(opc);
#endif
}
// MSUBC $acS.m, $axT.h
@@ -818,7 +726,6 @@ void DSPEmitter::maddc(const UDSPInstruction opc)
// product register.
void DSPEmitter::msubc(const UDSPInstruction opc)
{
#if _M_X86_64
u8 treg = (opc >> 8) & 0x1;
u8 sreg = (opc >> 9) & 0x1;
@@ -830,9 +737,6 @@ void DSPEmitter::msubc(const UDSPInstruction opc)
multiply_sub();
// dsp_set_long_prod(prod);
set_long_prod();
#else
Default(opc);
#endif
}
// MADD $axS.l, $axS.h
@@ -842,7 +746,6 @@ void DSPEmitter::msubc(const UDSPInstruction opc)
// result to product register.
void DSPEmitter::madd(const UDSPInstruction opc)
{
#if _M_X86_64
u8 sreg = (opc >> 8) & 0x1;
// u16 axl = dsp_get_ax_l(sreg);
@@ -853,9 +756,6 @@ void DSPEmitter::madd(const UDSPInstruction opc)
multiply_add();
// dsp_set_long_prod(prod);
set_long_prod();
#else
Default(opc);
#endif
}
// MSUB $axS.l, $axS.h
@@ -865,7 +765,6 @@ void DSPEmitter::madd(const UDSPInstruction opc)
// subtract result from product register.
void DSPEmitter::msub(const UDSPInstruction opc)
{
#if _M_X86_64
u8 sreg = (opc >> 8) & 0x1;
// u16 axl = dsp_get_ax_l(sreg);
@@ -876,7 +775,4 @@ void DSPEmitter::msub(const UDSPInstruction opc)
multiply_sub();
// dsp_set_long_prod(prod);
set_long_prod();
#else
Default(opc);
#endif
}
+1 -93
View File
@@ -62,13 +62,11 @@ static void *reg_ptr(int reg)
case DSP_REG_AX0_32:
case DSP_REG_AX1_32:
return &g_dsp.r.ax[reg - DSP_REG_AX0_32].val;
#if _M_X86_64
case DSP_REG_ACC0_64:
case DSP_REG_ACC1_64:
return &g_dsp.r.ac[reg - DSP_REG_ACC0_64].val;
case DSP_REG_PROD_64:
return &g_dsp.r.prod.val;
#endif
default:
_assert_msg_(DSPLLE, 0, "cannot happen");
return nullptr;
@@ -101,7 +99,6 @@ DSPJitRegCache::DSPJitRegCache(DSPEmitter &_emitter)
xregs[RSI].guest_reg = DSP_REG_NONE;
xregs[RDI].guest_reg = DSP_REG_NONE;
#if _M_X86_64
#ifdef STATIC_REG_ACCS
xregs[R8].guest_reg = DSP_REG_STATIC; //acc0
xregs[R9].guest_reg = DSP_REG_STATIC; //acc1
@@ -115,7 +112,6 @@ DSPJitRegCache::DSPJitRegCache(DSPEmitter &_emitter)
xregs[R13].guest_reg = DSP_REG_NONE;
xregs[R14].guest_reg = DSP_REG_NONE;
xregs[R15].guest_reg = DSP_REG_NONE;
#endif
for (unsigned int i = 0; i <= DSP_REG_MAX_MEM_BACKED; i++)
{
@@ -135,7 +131,6 @@ DSPJitRegCache::DSPJitRegCache(DSPEmitter &_emitter)
regs[i].size = 2;
}
//special composite registers
#if _M_X86_64
#ifdef STATIC_REG_ACCS
regs[DSP_REG_ACC0_64].host_reg = R8;
regs[DSP_REG_ACC1_64].host_reg = R9;
@@ -160,7 +155,6 @@ DSPJitRegCache::DSPJitRegCache(DSPEmitter &_emitter)
regs[DSP_REG_PRODM].shift = 16;
regs[DSP_REG_PRODH].shift = 32;
regs[DSP_REG_PRODM2].shift = 48;
#endif
for (unsigned int i = 0; i < 2; i++)
{
@@ -375,7 +369,6 @@ void DSPJitRegCache::flushRegs()
_assert_msg_(DSPLLE,
xregs[RDI].guest_reg == DSP_REG_NONE,
"wrong xreg state for %d", RDI);
#if _M_X86_64
#ifdef STATIC_REG_ACCS
_assert_msg_(DSPLLE,
xregs[R8].guest_reg == DSP_REG_STATIC,
@@ -409,7 +402,6 @@ void DSPJitRegCache::flushRegs()
_assert_msg_(DSPLLE,
xregs[R15].guest_reg == DSP_REG_NONE,
"wrong xreg state for %d", R15);
#endif
use_ctr = 0;
}
@@ -428,11 +420,7 @@ void DSPJitRegCache::loadRegs(bool emit)
if (emit)
{
#if _M_X86_64
emitter.MOV(64, M(&ebp_store), R(RBP));
#else
emitter.MOV(32, M(&ebp_store), R(EBP));
#endif
}
}
@@ -455,11 +443,7 @@ void DSPJitRegCache::saveRegs()
"register %x is still a simple reg", i);
}
#if _M_X86_64
emitter.MOV(64, R(RBP), M(&ebp_store));
#else
emitter.MOV(32, R(EBP), M(&ebp_store));
#endif
}
void DSPJitRegCache::pushRegs()
@@ -482,17 +466,10 @@ void DSPJitRegCache::pushRegs()
}
//hardcoding alignment to 16 bytes
#if _M_X86_64
if (push_count & 1)
{
emitter.SUB(64,R(RSP),Imm32(8));
}
#else
if (push_count & 3)
{
emitter.SUB(32,R(ESP),Imm32(16 - 4 * (push_count & 3)));
}
#endif
for (unsigned int i = 0; i < NUMXREGS; i++)
{
@@ -519,19 +496,11 @@ void DSPJitRegCache::pushRegs()
"register %x is still used", i);
}
#if _M_X86_64
emitter.MOV(64, R(RBP), M(&ebp_store));
#else
emitter.MOV(32, R(EBP), M(&ebp_store));
#endif
}
void DSPJitRegCache::popRegs() {
#if _M_X86_64
emitter.MOV(64, M(&ebp_store), R(RBP));
#else
emitter.MOV(32, M(&ebp_store), R(EBP));
#endif
int push_count = 0;
for (X64CachedReg& xreg : xregs)
{
@@ -552,17 +521,10 @@ void DSPJitRegCache::popRegs() {
}
//hardcoding alignment to 16 bytes
#if _M_X86_64
if (push_count & 1)
{
emitter.ADD(64,R(RSP),Imm32(8));
}
#else
if (push_count & 3)
{
emitter.ADD(32,R(ESP),Imm32(16 - 4 * (push_count & 3)));
}
#endif
for (unsigned int i = 0; i <= DSP_REG_MAX_MEM_BACKED; i++)
{
@@ -589,11 +551,7 @@ X64Reg DSPJitRegCache::makeABICallSafe(X64Reg reg)
emitter.INT3();
}
xregs[RBP].guest_reg = rbp_guest;
#if _M_X86_64
emitter.MOV(64,R(safe),R(reg));
#else
emitter.MOV(32,R(safe),R(reg));
#endif
return safe;
}
@@ -626,11 +584,9 @@ void DSPJitRegCache::movToHostReg(size_t reg, X64Reg host_reg, bool load)
case 4:
emitter.MOV(32, R(host_reg), regs[reg].loc);
break;
#if _M_X86_64
case 8:
emitter.MOV(64, R(host_reg), regs[reg].loc);
break;
#endif
default:
_assert_msg_(DSPLLE, 0, "unsupported memory size");
break;
@@ -698,11 +654,9 @@ void DSPJitRegCache::rotateHostReg(size_t reg, int shift, bool emit)
case 4:
emitter.ROR(32, regs[reg].loc, Imm8(shift - regs[reg].shift));
break;
#if _M_X86_64
case 8:
emitter.ROR(64, regs[reg].loc, Imm8(shift - regs[reg].shift));
break;
#endif
}
}
else if (shift < regs[reg].shift && emit)
@@ -715,11 +669,9 @@ void DSPJitRegCache::rotateHostReg(size_t reg, int shift, bool emit)
case 4:
emitter.ROL(32, regs[reg].loc, Imm8(regs[reg].shift - shift));
break;
#if _M_X86_64
case 8:
emitter.ROL(64, regs[reg].loc, Imm8(regs[reg].shift - shift));
break;
#endif
}
}
regs[reg].shift = shift;
@@ -770,11 +722,9 @@ void DSPJitRegCache::movToMemory(size_t reg)
case 4:
emitter.MOV(32, tmp, regs[reg].loc);
break;
#if _M_X86_64
case 8:
emitter.MOV(64, tmp, regs[reg].loc);
break;
#endif
default:
_assert_msg_(DSPLLE, 0, "unsupported memory size");
break;
@@ -837,7 +787,6 @@ void DSPJitRegCache::getReg(int reg, OpArg &oparg, bool load)
//do some register specific fixup
switch (reg)
{
#if _M_X86_64
case DSP_REG_ACC0_64:
case DSP_REG_ACC1_64:
if (load)
@@ -848,7 +797,6 @@ void DSPJitRegCache::getReg(int reg, OpArg &oparg, bool load)
emitter.SAR(64, oparg, Imm8(64-40));
}
break;
#endif
default:
break;
}
@@ -876,22 +824,7 @@ void DSPJitRegCache::putReg(int reg, bool dirty)
// (if at all)
// sign extend from the bottom 8 bits.
#if _M_X86_32
// cannot use movsx with SPL, BPL, SIL or DIL
// on 32 bit
if (oparg.GetSimpleReg() == RSP ||
oparg.GetSimpleReg() == RBP ||
oparg.GetSimpleReg() == RSI ||
oparg.GetSimpleReg() == RDI)
{
emitter.SHL(16,oparg,Imm8(8));
emitter.SAR(16,oparg,Imm8(8));
}
else
#endif
{
emitter.MOVSX(16, 8, oparg.GetSimpleReg(), oparg);
}
emitter.MOVSX(16, 8, oparg.GetSimpleReg(), oparg);
}
else if (oparg.IsImm())
{
@@ -910,7 +843,6 @@ void DSPJitRegCache::putReg(int reg, bool dirty)
}
}
break;
#if _M_X86_64
case DSP_REG_ACC0_64:
case DSP_REG_ACC1_64:
if (dirty)
@@ -919,7 +851,6 @@ void DSPJitRegCache::putReg(int reg, bool dirty)
emitter.SAR(64, oparg, Imm8(64-40));
}
break;
#endif
default:
break;
}
@@ -944,28 +875,18 @@ void DSPJitRegCache::readReg(int sreg, X64Reg host_dreg, DSPJitSignExtend extend
case 2:
switch (extend)
{
#if _M_X86_64
case SIGN:
emitter.MOVSX(64, 16, host_dreg, reg);
break;
case ZERO:
emitter.MOVZX(64, 16, host_dreg, reg);
break;
#else
case SIGN:
emitter.MOVSX(32, 16, host_dreg, reg);
break;
case ZERO:
emitter.MOVZX(32, 16, host_dreg, reg);
break;
#endif
case NONE:
emitter.MOV(16, R(host_dreg), reg);
break;
}
break;
case 4:
#if _M_X86_64
switch (extend)
{
case SIGN:
@@ -978,15 +899,10 @@ void DSPJitRegCache::readReg(int sreg, X64Reg host_dreg, DSPJitSignExtend extend
emitter.MOV(32, R(host_dreg), reg);
break;
}
#else
emitter.MOV(32, R(host_dreg), reg);
#endif
break;
#if _M_X86_64
case 8:
emitter.MOV(64, R(host_dreg), reg);
break;
#endif
default:
_assert_msg_(DSPLLE, 0, "unsupported memory size");
break;
@@ -1008,7 +924,6 @@ void DSPJitRegCache::writeReg(int dreg, OpArg arg)
case 4:
emitter.MOV(32, reg, Imm32((u32) arg.offset));
break;
#if _M_X86_64
case 8:
if ((u32) arg.offset == arg.offset)
{
@@ -1019,7 +934,6 @@ void DSPJitRegCache::writeReg(int dreg, OpArg arg)
emitter.MOV(64, reg, Imm64(arg.offset));
}
break;
#endif
default:
_assert_msg_(DSPLLE, 0, "unsupported memory size");
break;
@@ -1035,11 +949,9 @@ void DSPJitRegCache::writeReg(int dreg, OpArg arg)
case 4:
emitter.MOV(32, reg, arg);
break;
#if _M_X86_64
case 8:
emitter.MOV(64, reg, arg);
break;
#endif
default:
_assert_msg_(DSPLLE, 0, "unsupported memory size");
break;
@@ -1051,11 +963,7 @@ void DSPJitRegCache::writeReg(int dreg, OpArg arg)
//ordered in order of prefered use
//not all of these are actually available
static X64Reg alloc_order[] = {
#if _M_X86_64
R8,R9,R10,R11,R12,R13,R14,R15,RSI,RDI,RBX,RCX,RDX,RAX,RBP
#else
ESI,EDI,EBX,ECX,EDX,EAX,EBP
#endif
};
X64Reg DSPJitRegCache::spillXReg()
@@ -12,14 +12,10 @@ enum DSPJitRegSpecial
{
DSP_REG_AX0_32 =32,
DSP_REG_AX1_32 =33,
#if _M_X86_64
DSP_REG_ACC0_64 =34,
DSP_REG_ACC1_64 =35,
DSP_REG_PROD_64 =36,
DSP_REG_MAX_MEM_BACKED = 36,
#else
DSP_REG_MAX_MEM_BACKED = 33,
#endif
DSP_REG_USED =253,
DSP_REG_STATIC =254,
@@ -33,11 +29,7 @@ enum DSPJitSignExtend
NONE
};
#if _M_X86_64
#define NUMXREGS 16
#else
#define NUMXREGS 8
#endif
class DSPJitRegCache
{
-111
View File
@@ -25,11 +25,7 @@ void DSPEmitter::dsp_reg_stack_push(int stack_reg)
gpr.getFreeXReg(tmp1);
//g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg];
MOV(16, R(tmp1), M(&g_dsp.r.st[stack_reg]));
#if _M_X86_64
MOVZX(64, 8, RAX, R(AL));
#else
MOVZX(32, 8, EAX, R(AL));
#endif
MOV(16, MComplex(EAX, EAX, 1,
PtrOffset(&g_dsp.reg_stack[stack_reg][0],nullptr)), R(tmp1));
gpr.putXReg(tmp1);
@@ -44,11 +40,7 @@ void DSPEmitter::dsp_reg_stack_pop(int stack_reg)
MOV(8, R(AL), M(&g_dsp.reg_stack_ptr[stack_reg]));
X64Reg tmp1;
gpr.getFreeXReg(tmp1);
#if _M_X86_64
MOVZX(64, 8, RAX, R(AL));
#else
MOVZX(32, 8, EAX, R(AL));
#endif
MOV(16, R(tmp1), MComplex(EAX, EAX, 1,
PtrOffset(&g_dsp.reg_stack[stack_reg][0],nullptr)));
MOV(16, M(&g_dsp.r.st[stack_reg]), R(tmp1));
@@ -207,18 +199,10 @@ void DSPEmitter::dsp_op_read_reg_dont_saturate(int reg, Gen::X64Reg host_dreg, D
switch (extend)
{
case SIGN:
#if _M_X86_64
MOVSX(64, 16, host_dreg, R(host_dreg));
#else
MOVSX(32, 16, host_dreg, R(host_dreg));
#endif
break;
case ZERO:
#if _M_X86_64
MOVZX(64, 16, host_dreg, R(host_dreg));
#else
MOVZX(32, 16, host_dreg, R(host_dreg));
#endif
break;
case NONE:
default:
@@ -243,18 +227,10 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExten
switch (extend)
{
case SIGN:
#if _M_X86_64
MOVSX(64, 16, host_dreg, R(host_dreg));
#else
MOVSX(32, 16, host_dreg, R(host_dreg));
#endif
break;
case ZERO:
#if _M_X86_64
MOVZX(64, 16, host_dreg, R(host_dreg));
#else
MOVZX(32, 16, host_dreg, R(host_dreg));
#endif
break;
case NONE:
default:
@@ -265,12 +241,8 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExten
case DSP_REG_ACM1:
{
//we already know this is ACCM0 or ACCM1
#if _M_X86_64
OpArg acc_reg;
gpr.getReg(reg-DSP_REG_ACM0+DSP_REG_ACC0_64, acc_reg);
#else
gpr.readReg(reg, host_dreg, extend);
#endif
OpArg sr_reg;
gpr.getReg(DSP_REG_SR,sr_reg);
@@ -278,8 +250,6 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExten
TEST(16, sr_reg, Imm16(SR_40_MODE_BIT));
FixupBranch not_40bit = J_CC(CC_Z, true);
#if _M_X86_64
MOVSX(64,32,host_dreg,acc_reg);
CMP(64,R(host_dreg),acc_reg);
FixupBranch no_saturate = J_CC(CC_Z);
@@ -309,42 +279,6 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExten
SetJumpTarget(done_negative);
gpr.flushRegs(c);
gpr.putReg(reg-DSP_REG_ACM0+DSP_REG_ACC0_64, false);
#else
DSPJitRegCache c2(gpr);
gpr.putReg(DSP_REG_SR, false);
X64Reg tmp1;
gpr.getFreeXReg(tmp1);
gpr.readReg(reg-DSP_REG_ACM0+DSP_REG_ACH0, tmp1, NONE);
MOVSX(32,16,host_dreg,R(host_dreg));
SHL(32, R(tmp1), Imm8(16));
MOV(16,R(tmp1),R(host_dreg));
CMP(32,R(host_dreg), R(tmp1));
FixupBranch no_saturate = J_CC(CC_Z);
CMP(32,R(tmp1),Imm32(0));
FixupBranch negative = J_CC(CC_LE);
MOV(32,R(host_dreg),Imm32(0x7fff));//this works for all extend modes
FixupBranch done_positive = J();
SetJumpTarget(negative);
if (extend == NONE || extend == ZERO)
MOV(32,R(host_dreg),Imm32(0x00008000));
else
MOV(32,R(host_dreg),Imm32(0xffff8000));
FixupBranch done_negative = J();
SetJumpTarget(no_saturate);
if (extend == ZERO)
MOVZX(32,16,host_dreg,R(host_dreg));
SetJumpTarget(done_positive);
SetJumpTarget(done_negative);
gpr.putXReg(tmp1);
gpr.flushRegs(c2);
SetJumpTarget(not_40bit);
gpr.flushRegs(c);
#endif
gpr.putReg(DSP_REG_SR, false);
}
@@ -585,11 +519,7 @@ void DSPEmitter::dmem_write(X64Reg value)
// g_dsp.dram[addr & DSP_DRAM_MASK] = val;
AND(16, R(EAX), Imm16(DSP_DRAM_MASK));
#if _M_X86_64
MOV(64, R(ECX), ImmPtr(g_dsp.dram));
#else
MOV(32, R(ECX), ImmPtr(g_dsp.dram));
#endif
MOV(16, MComplex(ECX, EAX, 2, 0), R(value));
FixupBranch end = J(true);
@@ -610,12 +540,8 @@ void DSPEmitter::dmem_write_imm(u16 address, X64Reg value)
switch (address >> 12)
{
case 0x0: // 0xxx DRAM
#if _M_X86_64
MOV(64, R(RDX), ImmPtr(g_dsp.dram));
MOV(16, MDisp(RDX, (address & DSP_DRAM_MASK)*2), R(value));
#else
MOV(16, M(&g_dsp.dram[address & DSP_DRAM_MASK]), R(value));
#endif
break;
case 0xf: // Fxxx HW regs
@@ -644,11 +570,7 @@ void DSPEmitter::imem_read(X64Reg address)
FixupBranch irom = J_CC(CC_A);
// return g_dsp.iram[addr & DSP_IRAM_MASK];
AND(16, R(address), Imm16(DSP_IRAM_MASK));
#if _M_X86_64
MOV(64, R(ECX), ImmPtr(g_dsp.iram));
#else
MOV(32, R(ECX), ImmPtr(g_dsp.iram));
#endif
MOV(16, R(EAX), MComplex(ECX, address, 2, 0));
FixupBranch end = J();
@@ -656,11 +578,7 @@ void DSPEmitter::imem_read(X64Reg address)
// else if (addr == 0x8)
// return g_dsp.irom[addr & DSP_IROM_MASK];
AND(16, R(address), Imm16(DSP_IROM_MASK));
#if _M_X86_64
MOV(64, R(ECX), ImmPtr(g_dsp.irom));
#else
MOV(32, R(ECX), ImmPtr(g_dsp.irom));
#endif
MOV(16, R(EAX), MComplex(ECX, address, 2, 0));
SetJumpTarget(end);
@@ -676,12 +594,8 @@ void DSPEmitter::dmem_read(X64Reg address)
FixupBranch dram = J_CC(CC_A);
// return g_dsp.dram[addr & DSP_DRAM_MASK];
AND(32, R(address), Imm32(DSP_DRAM_MASK));
#if _M_X86_64
MOVZX(64, 16, address, R(address));
MOV(64, R(ECX), ImmPtr(g_dsp.dram));
#else
MOV(32, R(ECX), ImmPtr(g_dsp.dram));
#endif
MOV(16, R(EAX), MComplex(ECX, address, 2, 0));
FixupBranch end = J(true);
@@ -691,12 +605,8 @@ void DSPEmitter::dmem_read(X64Reg address)
FixupBranch ifx = J_CC(CC_A);
// return g_dsp.coef[addr & DSP_COEF_MASK];
AND(32, R(address), Imm32(DSP_COEF_MASK));
#if _M_X86_64
MOVZX(64, 16, address, R(address));
MOV(64, R(ECX), ImmPtr(g_dsp.coef));
#else
MOV(32, R(ECX), ImmPtr(g_dsp.coef));
#endif
MOV(16, R(EAX), MComplex(ECX, address, 2, 0));
FixupBranch end2 = J(true);
@@ -718,21 +628,13 @@ void DSPEmitter::dmem_read_imm(u16 address)
switch (address >> 12)
{
case 0x0: // 0xxx DRAM
#if _M_X86_64
MOV(64, R(RDX), ImmPtr(g_dsp.dram));
MOV(16, R(EAX), MDisp(RDX, (address & DSP_DRAM_MASK)*2));
#else
MOV(16, R(EAX), M(&g_dsp.dram[address & DSP_DRAM_MASK]));
#endif
break;
case 0x1: // 1xxx COEF
#if _M_X86_64
MOV(64, R(RDX), ImmPtr(g_dsp.coef));
MOV(16, R(EAX), MDisp(RDX, (address & DSP_COEF_MASK)*2));
#else
MOV(16, R(EAX), Imm16(g_dsp.coef[address & DSP_COEF_MASK]));
#endif
break;
case 0xf: // Fxxx HW regs
@@ -751,7 +653,6 @@ void DSPEmitter::dmem_read_imm(u16 address)
// Returns s64 in RAX
void DSPEmitter::get_long_prod(X64Reg long_prod)
{
#if _M_X86_64
//s64 val = (s8)(u8)g_dsp.r[DSP_REG_PRODH];
OpArg prod_reg;
gpr.getReg(DSP_REG_PROD_64, prod_reg);
@@ -767,15 +668,12 @@ void DSPEmitter::get_long_prod(X64Reg long_prod)
SHL(64, R(tmp), Imm8(16));
ADD(64, R(long_prod), R(tmp));
gpr.putXReg(tmp);
#endif
}
// Returns s64 in RAX
// Clobbers RCX
void DSPEmitter::get_long_prod_round_prodl(X64Reg long_prod)
{
#if _M_X86_64
//s64 prod = dsp_get_long_prod();
get_long_prod(long_prod);
@@ -796,7 +694,6 @@ void DSPEmitter::get_long_prod_round_prodl(X64Reg long_prod)
SetJumpTarget(_ret);
//return prod;
gpr.putXReg(tmp);
#endif
}
// For accurate emulation, this is wrong - but the real prod registers behave
@@ -804,7 +701,6 @@ void DSPEmitter::get_long_prod_round_prodl(X64Reg long_prod)
// In: RAX = s64 val
void DSPEmitter::set_long_prod()
{
#if _M_X86_64
X64Reg tmp;
gpr.getFreeXReg(tmp);
@@ -817,14 +713,12 @@ void DSPEmitter::set_long_prod()
MOV(64, prod_reg, R(RAX));
gpr.putReg(DSP_REG_PROD_64, true);
#endif
}
// Returns s64 in RAX
// Clobbers RCX
void DSPEmitter::round_long_acc(X64Reg long_acc)
{
#if _M_X86_64
//if (prod & 0x10000) prod = (prod + 0x8000) & ~0xffff;
TEST(32, R(long_acc), Imm32(0x10000));
FixupBranch jump = J_CC(CC_Z);
@@ -839,29 +733,24 @@ void DSPEmitter::round_long_acc(X64Reg long_acc)
AND(64, R(long_acc), R(RCX));
SetJumpTarget(_ret);
//return prod;
#endif
}
// Returns s64 in acc
void DSPEmitter::get_long_acc(int _reg, X64Reg acc)
{
#if _M_X86_64
OpArg reg;
gpr.getReg(DSP_REG_ACC0_64+_reg, reg);
MOV(64, R(acc), reg);
gpr.putReg(DSP_REG_ACC0_64+_reg, false);
#endif
}
// In: acc = s64 val
void DSPEmitter::set_long_acc(int _reg, X64Reg acc)
{
#if _M_X86_64
OpArg reg;
gpr.getReg(DSP_REG_ACC0_64+_reg, reg, false);
MOV(64, reg, R(acc));
gpr.putReg(DSP_REG_ACC0_64+_reg);
#endif
}
// Returns s16 in AX
+1 -10
View File
@@ -247,13 +247,8 @@ static void ImHere()
if (ImHereLog)
{
if (!f)
{
#if _M_X86_64
f.Open("log64.txt", "w");
#else
f.Open("log32.txt", "w");
#endif
}
fprintf(f.GetHandle(), "%08x\n", PC);
}
if (been_here.find(PC) != been_here.end())
@@ -651,12 +646,8 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_ISI));
// Remove the invalid instruction from the icache, forcing a recompile
#if _M_X86_32
MOV(32, M(jit->GetBlockCache()->GetICachePtr(js.compilerPC)), Imm32(JIT_ICACHE_INVALID_WORD));
#else
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICachePtr(js.compilerPC)));
MOV(32,MatR(RAX),Imm32(JIT_ICACHE_INVALID_WORD));
#endif
WriteExceptionExit();
}
-4
View File
@@ -76,11 +76,7 @@ public:
}
const char *GetName() override {
#if _M_X86_64
return "JIT64";
#else
return "JIT32";
#endif
}
// Run!

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