Assorted jit64-related bugfixes. Discovered and papered over nasty codegen bug. No, IL64 still doesn't work.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2281 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
33ea7313ba
commit
1c1425a406
|
@ -186,10 +186,17 @@ void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) {
|
|||
|
||||
// Pass a register as a paremeter.
|
||||
void XEmitter::ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2) {
|
||||
if (reg1 != ABI_PARAM1)
|
||||
MOV(32, R(ABI_PARAM1), R(reg1));
|
||||
if (reg2 != ABI_PARAM2)
|
||||
MOV(32, R(ABI_PARAM2), R(reg2));
|
||||
if (reg2 != ABI_PARAM1) {
|
||||
if (reg1 != ABI_PARAM1)
|
||||
MOV(32, R(ABI_PARAM1), R(reg1));
|
||||
if (reg2 != ABI_PARAM2)
|
||||
MOV(32, R(ABI_PARAM2), R(reg2));
|
||||
} else {
|
||||
if (reg2 != ABI_PARAM2)
|
||||
MOV(32, R(ABI_PARAM2), R(reg2));
|
||||
if (reg1 != ABI_PARAM1)
|
||||
MOV(32, R(ABI_PARAM1), R(reg1));
|
||||
}
|
||||
CALL(func);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,83 +1,82 @@
|
|||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include and declarations
|
||||
// ¯¯¯¯¯¯¯¯¯
|
||||
#include <stdio.h> // System
|
||||
|
||||
#include "Common.h" // Local
|
||||
#include "StringUtil.h"
|
||||
|
||||
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style);
|
||||
static MsgAlertHandler msg_handler = DefaultMsgHandler;
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
/* Select which of these functions that are used for message boxes. If wxWidgets is enabled
|
||||
we will use wxMsgAlert() that is defined in main.cpp */
|
||||
void RegisterMsgAlertHandler(MsgAlertHandler handler)
|
||||
{
|
||||
msg_handler = handler;
|
||||
}
|
||||
|
||||
// ¯¯¯¯¯¯¯¯¯
|
||||
#include <stdio.h> // System
|
||||
|
||||
#include "Common.h" // Local
|
||||
#include "StringUtil.h"
|
||||
|
||||
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style);
|
||||
static MsgAlertHandler msg_handler = DefaultMsgHandler;
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
/* Select which of these functions that are used for message boxes. If wxWidgets is enabled
|
||||
we will use wxMsgAlert() that is defined in main.cpp */
|
||||
void RegisterMsgAlertHandler(MsgAlertHandler handler)
|
||||
{
|
||||
msg_handler = handler;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
/* This is the first stop for messages where the log is updated and the correct windows
|
||||
is shown */
|
||||
// ¯¯¯¯¯¯¯¯¯
|
||||
bool MsgAlert(const char* caption, bool yes_no, int Style, const char* format, ...)
|
||||
{
|
||||
// ---------------------------------
|
||||
// Read message and write it to the log
|
||||
// -----------
|
||||
char buffer[2048];
|
||||
va_list args;
|
||||
bool ret = false;
|
||||
|
||||
va_start(args, format);
|
||||
CharArrayFromFormatV(buffer, 2048, format, args);
|
||||
|
||||
LOG(MASTER_LOG, "%s: %s", caption, buffer);
|
||||
// -----------
|
||||
|
||||
if (msg_handler) {
|
||||
ret = msg_handler(caption, buffer, yes_no, Style);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ¯¯¯¯¯¯¯¯¯
|
||||
bool MsgAlert(const char* caption, bool yes_no, int Style, const char* format, ...)
|
||||
{
|
||||
// ---------------------------------
|
||||
// Read message and write it to the log
|
||||
// -----------
|
||||
char buffer[2048];
|
||||
bool ret = false;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
CharArrayFromFormatV(buffer, 2047, format, args);
|
||||
va_end(args);
|
||||
|
||||
LOG(MASTER_LOG, "%s: %s", caption, buffer);
|
||||
// -----------
|
||||
|
||||
if (msg_handler) {
|
||||
ret = msg_handler(caption, buffer, yes_no, Style);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
/* This is used in the No-GUI build */
|
||||
// ¯¯¯¯¯¯¯¯¯
|
||||
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int STYLE = MB_ICONINFORMATION;
|
||||
if(Style == QUESTION) STYLE = MB_ICONQUESTION;
|
||||
if(Style == WARNING) STYLE = MB_ICONWARNING;
|
||||
|
||||
return IDYES == MessageBox(0, text, caption, STYLE | (yes_no ? MB_YESNO : MB_OK));
|
||||
|
||||
#else
|
||||
printf("%s\n", text);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ¯¯¯¯¯¯¯¯¯
|
||||
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int STYLE = MB_ICONINFORMATION;
|
||||
if (Style == QUESTION) STYLE = MB_ICONQUESTION;
|
||||
if (Style == WARNING) STYLE = MB_ICONWARNING;
|
||||
|
||||
return IDYES == MessageBox(0, text, caption, STYLE | (yes_no ? MB_YESNO : MB_OK));
|
||||
|
||||
#else
|
||||
printf("%s\n", text);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,8 @@ struct OpArg
|
|||
operandReg = 0;
|
||||
scale = (u8)_scale;
|
||||
offsetOrBaseReg = (u8)rmReg;
|
||||
if (rmReg == R12)
|
||||
PanicAlert("Codegen for R12 known buggy");
|
||||
indexReg = (u8)scaledReg;
|
||||
//if scale == 0 never mind offseting
|
||||
offset = _offset;
|
||||
|
@ -170,11 +172,14 @@ inline OpArg M(void *ptr) {return OpArg((u64)ptr, (int)SCALE_RIP);}
|
|||
inline OpArg R(X64Reg value) {return OpArg(0, SCALE_NONE, value);}
|
||||
inline OpArg MatR(X64Reg value) {return OpArg(0, SCALE_ATREG, value);}
|
||||
inline OpArg MDisp(X64Reg value, int offset) {
|
||||
return OpArg((u32)offset, SCALE_ATREG, value); }
|
||||
inline OpArg MComplex(X64Reg base, X64Reg scaled, int scale, int offset)
|
||||
{
|
||||
return OpArg((u32)offset, SCALE_ATREG, value);
|
||||
}
|
||||
inline OpArg MComplex(X64Reg base, X64Reg scaled, int scale, int offset) {
|
||||
return OpArg(offset, scale, base, scaled);
|
||||
}
|
||||
inline OpArg MRegSum(X64Reg base, X64Reg offset) {
|
||||
return MComplex(base, offset, 1, 0);
|
||||
}
|
||||
inline OpArg Imm8 (u8 imm) {return OpArg(imm, SCALE_IMM8);}
|
||||
inline OpArg Imm16(u16 imm) {return OpArg(imm, SCALE_IMM16);} //rarely used
|
||||
inline OpArg Imm32(u32 imm) {return OpArg(imm, SCALE_IMM32);}
|
||||
|
|
|
@ -579,7 +579,7 @@
|
|||
AssemblerListingLocation="$(IntDir)\"
|
||||
WarningLevel="3"
|
||||
WarnAsError="false"
|
||||
DebugInformationFormat="0"
|
||||
DebugInformationFormat="3"
|
||||
ForcedIncludeFiles="stdafx.h"
|
||||
/>
|
||||
<Tool
|
||||
|
|
|
@ -271,7 +271,9 @@ THREAD_RETURN CpuThread(void *pArg)
|
|||
{
|
||||
#ifdef _M_X64
|
||||
// Let's run under memory watch
|
||||
#ifndef JITTEST
|
||||
EMM::InstallExceptionHandler();
|
||||
#endif
|
||||
#else
|
||||
PanicAlert("32-bit platforms do not support fastmem yet. Report this bug.");
|
||||
#endif
|
||||
|
|
|
@ -31,9 +31,9 @@ namespace Memory
|
|||
// ----------------
|
||||
|
||||
// Pointers to low memory
|
||||
extern u8* m_pFakeVMEM;
|
||||
extern u8* m_pEXRAM; // Wii
|
||||
extern u8* m_pEFB;
|
||||
extern u8 *m_pFakeVMEM;
|
||||
extern u8 *m_pEXRAM; // Wii
|
||||
extern u8 *m_pEFB;
|
||||
|
||||
// Init
|
||||
extern bool m_IsInitialized;
|
||||
|
@ -43,7 +43,6 @@ extern bool bFakeVMEM;
|
|||
extern writeFn8 hwWrite8 [NUMHWMEMFUN];
|
||||
extern writeFn16 hwWrite16[NUMHWMEMFUN];
|
||||
extern writeFn32 hwWrite32[NUMHWMEMFUN];
|
||||
extern writeFn64 hwWrite64[NUMHWMEMFUN];
|
||||
|
||||
extern readFn8 hwRead8 [NUMHWMEMFUN];
|
||||
extern readFn16 hwRead16[NUMHWMEMFUN];
|
||||
|
@ -52,7 +51,6 @@ extern readFn32 hwRead32[NUMHWMEMFUN];
|
|||
extern writeFn8 hwWriteWii8 [NUMHWMEMFUN];
|
||||
extern writeFn16 hwWriteWii16[NUMHWMEMFUN];
|
||||
extern writeFn32 hwWriteWii32[NUMHWMEMFUN];
|
||||
extern writeFn64 hwWriteWii64[NUMHWMEMFUN];
|
||||
|
||||
extern readFn8 hwReadWii8 [NUMHWMEMFUN];
|
||||
extern readFn16 hwReadWii16[NUMHWMEMFUN];
|
||||
|
|
|
@ -202,11 +202,12 @@ const int *GPRRegCache::GetAllocationOrder(int &count)
|
|||
{
|
||||
static const int allocationOrder[] =
|
||||
{
|
||||
// R12, when used as base register, for example in a LEA, can generate bad code! Need to look into this.
|
||||
#ifdef _M_X64
|
||||
#ifdef _WIN32
|
||||
RSI, RDI, R12, R13, R14, R8, R9, R10, R11 //, RCX
|
||||
RSI, RDI, R13, R14, R8, R9, R10, R11 //, RCX
|
||||
#else
|
||||
RBP, R12, R13, R14, R8, R9, R10, R11, //, RCX
|
||||
RBP, R13, R14, R8, R9, R10, R11, //, RCX
|
||||
#endif
|
||||
#elif _M_IX86
|
||||
ESI, EDI, EBX, EBP, EDX, ECX,
|
||||
|
@ -221,7 +222,7 @@ const int *FPURegCache::GetAllocationOrder(int &count)
|
|||
static const int allocationOrder[] =
|
||||
{
|
||||
#ifdef _M_X64
|
||||
XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, XMM2, XMM3, XMM4, XMM5
|
||||
XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM13, XMM14, XMM15, XMM2, XMM3, XMM4, XMM5
|
||||
#elif _M_IX86
|
||||
XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
|
||||
#endif
|
||||
|
|
|
@ -160,7 +160,7 @@
|
|||
{
|
||||
case 32:
|
||||
accessSize = 32;
|
||||
if(Core::g_CoreStartupParameter.bJITLoadStorelwzOff) {Default(inst); return;}
|
||||
if (Core::g_CoreStartupParameter.bJITLoadStorelwzOff) {Default(inst); return;}
|
||||
break; //lwz
|
||||
case 40: accessSize = 16; break; //lhz
|
||||
case 34: accessSize = 8; break; //lbz
|
||||
|
|
|
@ -716,7 +716,7 @@ struct RegInfo {
|
|||
}
|
||||
|
||||
private:
|
||||
RegInfo(RegInfo&); // DO NOT IMPLEMENT
|
||||
RegInfo(RegInfo&); // DO NOT IMPLEMENT
|
||||
};
|
||||
|
||||
static void regMarkUse(RegInfo& R, InstLoc I, InstLoc Op, unsigned OpNum) {
|
||||
|
@ -791,9 +791,9 @@ static void fregSpill(RegInfo& RI, X64Reg reg) {
|
|||
|
||||
// 64-bit - calling conventions differ between linux & windows, so...
|
||||
#ifdef _WIN32
|
||||
static const X64Reg RegAllocOrder[] = {RSI, RDI, R12, R13, R14, R8, R9, R10, R11};
|
||||
static const X64Reg RegAllocOrder[] = {RSI, RDI, R13, R14, R8, R9, R10, R11};
|
||||
#else
|
||||
static const X64Reg RegAllocOrder[] = {RBP, R12, R13, R14, R8, R9, R10, R11};
|
||||
static const X64Reg RegAllocOrder[] = {RBP, R13, R14, R8, R9, R10, R11};
|
||||
#endif
|
||||
static const int RegAllocSize = sizeof(RegAllocOrder) / sizeof(X64Reg);
|
||||
static const X64Reg FRegAllocOrder[] = {XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, XMM2, XMM3, XMM4, XMM5};
|
||||
|
@ -883,9 +883,22 @@ static X64Reg fregEnsureInReg(RegInfo& RI, InstLoc I) {
|
|||
}
|
||||
|
||||
static void regSpillCallerSaved(RegInfo& RI) {
|
||||
#ifdef _M_IX86
|
||||
// 32-bit
|
||||
regSpill(RI, EDX);
|
||||
regSpill(RI, ECX);
|
||||
regSpill(RI, EAX);
|
||||
#else
|
||||
// 64-bit
|
||||
regSpill(RI, RCX);
|
||||
regSpill(RI, RDX);
|
||||
regSpill(RI, RSI);
|
||||
regSpill(RI, RDI);
|
||||
regSpill(RI, R8);
|
||||
regSpill(RI, R9);
|
||||
regSpill(RI, R10);
|
||||
regSpill(RI, R11);
|
||||
#endif
|
||||
}
|
||||
|
||||
static X64Reg regUReg(RegInfo& RI, InstLoc I) {
|
||||
|
@ -998,6 +1011,7 @@ static void regClearDeadMemAddress(RegInfo& RI, InstLoc I, InstLoc AI, unsigned
|
|||
regClearInst(RI, AddrBase);
|
||||
}
|
||||
|
||||
// in 64-bit build, this returns a completely bizarre address sometimes!
|
||||
static OpArg regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI,
|
||||
unsigned OpNum, unsigned Size, X64Reg* dest,
|
||||
bool Profiled,
|
||||
|
@ -1015,7 +1029,7 @@ static OpArg regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI,
|
|||
#else
|
||||
// 64-bit
|
||||
if (Profiled)
|
||||
return M((void*)((u8*)Memory::base + addr));
|
||||
return MDisp(RBX, addr);
|
||||
return M((void*)addr);
|
||||
#endif
|
||||
}
|
||||
|
@ -1030,6 +1044,7 @@ static OpArg regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI,
|
|||
AddrBase = AI;
|
||||
}
|
||||
X64Reg baseReg;
|
||||
// Ok, this stuff needs a comment or three :P -ector
|
||||
if (RI.IInfo[I - RI.FirstI] & (2 << OpNum)) {
|
||||
baseReg = regEnsureInReg(RI, AddrBase);
|
||||
regClearInst(RI, AddrBase);
|
||||
|
@ -1053,7 +1068,7 @@ static OpArg regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI,
|
|||
#ifdef _M_IX86
|
||||
return MDisp(baseReg, (u32)Memory::base + offset + ProfileOffset);
|
||||
#else
|
||||
return MDisp(RBX, offset + ProfileOffset);
|
||||
return MComplex(RBX, baseReg, 1, offset + ProfileOffset);
|
||||
#endif
|
||||
}
|
||||
return MDisp(baseReg, offset);
|
||||
|
|
|
@ -204,9 +204,9 @@ const int *GPRRegCache::GetAllocationOrder(int &count)
|
|||
{
|
||||
#ifdef _M_X64
|
||||
#ifdef _WIN32
|
||||
RSI, RDI, R12, R13, R14, R8, R9, R10, R11 //, RCX
|
||||
RSI, RDI, R13, R14, R8, R9, R10, R11 //, RCX
|
||||
#else
|
||||
RBP, R12, R13, R14, R8, R9, R10, R11, //, RCX
|
||||
RBP, R13, R14, R8, R9, R10, R11, //, RCX
|
||||
#endif
|
||||
#elif _M_IX86
|
||||
ESI, EDI, EBX, EBP, EDX, ECX,
|
||||
|
|
Loading…
Reference in New Issue