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:
hrydgard 2009-02-16 22:06:11 +00:00
parent 33ea7313ba
commit 1c1425a406
10 changed files with 127 additions and 100 deletions

View File

@ -186,10 +186,17 @@ void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) {
// Pass a register as a paremeter. // Pass a register as a paremeter.
void XEmitter::ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2) { void XEmitter::ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2) {
if (reg1 != ABI_PARAM1) if (reg2 != ABI_PARAM1) {
MOV(32, R(ABI_PARAM1), R(reg1)); if (reg1 != ABI_PARAM1)
if (reg2 != ABI_PARAM2) MOV(32, R(ABI_PARAM1), R(reg1));
MOV(32, R(ABI_PARAM2), R(reg2)); 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); CALL(func);
} }

View File

@ -1,83 +1,82 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
// Include and declarations // Include and declarations
// ¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯
#include <stdio.h> // System #include <stdio.h> // System
#include "Common.h" // Local #include "Common.h" // Local
#include "StringUtil.h" #include "StringUtil.h"
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style); bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style);
static MsgAlertHandler msg_handler = DefaultMsgHandler; static MsgAlertHandler msg_handler = DefaultMsgHandler;
///////////////////////////// /////////////////////////////
/* Select which of these functions that are used for message boxes. If wxWidgets is enabled /* 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 */ we will use wxMsgAlert() that is defined in main.cpp */
void RegisterMsgAlertHandler(MsgAlertHandler handler) void RegisterMsgAlertHandler(MsgAlertHandler handler)
{ {
msg_handler = handler; msg_handler = handler;
} }
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
/* This is the first stop for messages where the log is updated and the correct windows /* This is the first stop for messages where the log is updated and the correct windows
is shown */ is shown */
// ¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯
bool MsgAlert(const char* caption, bool yes_no, int Style, const char* format, ...) bool MsgAlert(const char* caption, bool yes_no, int Style, const char* format, ...)
{ {
// --------------------------------- // ---------------------------------
// Read message and write it to the log // Read message and write it to the log
// ----------- // -----------
char buffer[2048]; char buffer[2048];
va_list args; bool ret = false;
bool ret = false;
va_list args;
va_start(args, format); va_start(args, format);
CharArrayFromFormatV(buffer, 2048, format, args); CharArrayFromFormatV(buffer, 2047, format, args);
va_end(args);
LOG(MASTER_LOG, "%s: %s", caption, buffer);
// ----------- LOG(MASTER_LOG, "%s: %s", caption, buffer);
// -----------
if (msg_handler) {
ret = msg_handler(caption, buffer, yes_no, Style); if (msg_handler) {
} ret = msg_handler(caption, buffer, yes_no, Style);
}
va_end(args); return ret;
return ret; }
}
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
/* This is used in the No-GUI build */ /* This is used in the No-GUI build */
// ¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style) bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style)
{ {
#ifdef _WIN32 #ifdef _WIN32
int STYLE = MB_ICONINFORMATION; int STYLE = MB_ICONINFORMATION;
if(Style == QUESTION) STYLE = MB_ICONQUESTION; if (Style == QUESTION) STYLE = MB_ICONQUESTION;
if(Style == WARNING) STYLE = MB_ICONWARNING; if (Style == WARNING) STYLE = MB_ICONWARNING;
return IDYES == MessageBox(0, text, caption, STYLE | (yes_no ? MB_YESNO : MB_OK)); return IDYES == MessageBox(0, text, caption, STYLE | (yes_no ? MB_YESNO : MB_OK));
#else #else
printf("%s\n", text); printf("%s\n", text);
return true; return true;
#endif #endif
} }

View File

@ -114,6 +114,8 @@ struct OpArg
operandReg = 0; operandReg = 0;
scale = (u8)_scale; scale = (u8)_scale;
offsetOrBaseReg = (u8)rmReg; offsetOrBaseReg = (u8)rmReg;
if (rmReg == R12)
PanicAlert("Codegen for R12 known buggy");
indexReg = (u8)scaledReg; indexReg = (u8)scaledReg;
//if scale == 0 never mind offseting //if scale == 0 never mind offseting
offset = _offset; 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 R(X64Reg value) {return OpArg(0, SCALE_NONE, value);}
inline OpArg MatR(X64Reg value) {return OpArg(0, SCALE_ATREG, value);} inline OpArg MatR(X64Reg value) {return OpArg(0, SCALE_ATREG, value);}
inline OpArg MDisp(X64Reg value, int offset) { inline OpArg MDisp(X64Reg value, int offset) {
return OpArg((u32)offset, SCALE_ATREG, value); } return OpArg((u32)offset, SCALE_ATREG, value);
inline OpArg MComplex(X64Reg base, X64Reg scaled, int scale, int offset) }
{ inline OpArg MComplex(X64Reg base, X64Reg scaled, int scale, int offset) {
return OpArg(offset, scale, base, scaled); 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 Imm8 (u8 imm) {return OpArg(imm, SCALE_IMM8);}
inline OpArg Imm16(u16 imm) {return OpArg(imm, SCALE_IMM16);} //rarely used inline OpArg Imm16(u16 imm) {return OpArg(imm, SCALE_IMM16);} //rarely used
inline OpArg Imm32(u32 imm) {return OpArg(imm, SCALE_IMM32);} inline OpArg Imm32(u32 imm) {return OpArg(imm, SCALE_IMM32);}

View File

@ -579,7 +579,7 @@
AssemblerListingLocation="$(IntDir)\" AssemblerListingLocation="$(IntDir)\"
WarningLevel="3" WarningLevel="3"
WarnAsError="false" WarnAsError="false"
DebugInformationFormat="0" DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h" ForcedIncludeFiles="stdafx.h"
/> />
<Tool <Tool

View File

@ -271,7 +271,9 @@ THREAD_RETURN CpuThread(void *pArg)
{ {
#ifdef _M_X64 #ifdef _M_X64
// Let's run under memory watch // Let's run under memory watch
#ifndef JITTEST
EMM::InstallExceptionHandler(); EMM::InstallExceptionHandler();
#endif
#else #else
PanicAlert("32-bit platforms do not support fastmem yet. Report this bug."); PanicAlert("32-bit platforms do not support fastmem yet. Report this bug.");
#endif #endif

View File

@ -31,9 +31,9 @@ namespace Memory
// ---------------- // ----------------
// Pointers to low memory // Pointers to low memory
extern u8* m_pFakeVMEM; extern u8 *m_pFakeVMEM;
extern u8* m_pEXRAM; // Wii extern u8 *m_pEXRAM; // Wii
extern u8* m_pEFB; extern u8 *m_pEFB;
// Init // Init
extern bool m_IsInitialized; extern bool m_IsInitialized;
@ -43,7 +43,6 @@ extern bool bFakeVMEM;
extern writeFn8 hwWrite8 [NUMHWMEMFUN]; extern writeFn8 hwWrite8 [NUMHWMEMFUN];
extern writeFn16 hwWrite16[NUMHWMEMFUN]; extern writeFn16 hwWrite16[NUMHWMEMFUN];
extern writeFn32 hwWrite32[NUMHWMEMFUN]; extern writeFn32 hwWrite32[NUMHWMEMFUN];
extern writeFn64 hwWrite64[NUMHWMEMFUN];
extern readFn8 hwRead8 [NUMHWMEMFUN]; extern readFn8 hwRead8 [NUMHWMEMFUN];
extern readFn16 hwRead16[NUMHWMEMFUN]; extern readFn16 hwRead16[NUMHWMEMFUN];
@ -52,7 +51,6 @@ extern readFn32 hwRead32[NUMHWMEMFUN];
extern writeFn8 hwWriteWii8 [NUMHWMEMFUN]; extern writeFn8 hwWriteWii8 [NUMHWMEMFUN];
extern writeFn16 hwWriteWii16[NUMHWMEMFUN]; extern writeFn16 hwWriteWii16[NUMHWMEMFUN];
extern writeFn32 hwWriteWii32[NUMHWMEMFUN]; extern writeFn32 hwWriteWii32[NUMHWMEMFUN];
extern writeFn64 hwWriteWii64[NUMHWMEMFUN];
extern readFn8 hwReadWii8 [NUMHWMEMFUN]; extern readFn8 hwReadWii8 [NUMHWMEMFUN];
extern readFn16 hwReadWii16[NUMHWMEMFUN]; extern readFn16 hwReadWii16[NUMHWMEMFUN];

View File

@ -202,11 +202,12 @@ const int *GPRRegCache::GetAllocationOrder(int &count)
{ {
static const int allocationOrder[] = 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 _M_X64
#ifdef _WIN32 #ifdef _WIN32
RSI, RDI, R12, R13, R14, R8, R9, R10, R11 //, RCX RSI, RDI, R13, R14, R8, R9, R10, R11 //, RCX
#else #else
RBP, R12, R13, R14, R8, R9, R10, R11, //, RCX RBP, R13, R14, R8, R9, R10, R11, //, RCX
#endif #endif
#elif _M_IX86 #elif _M_IX86
ESI, EDI, EBX, EBP, EDX, ECX, ESI, EDI, EBX, EBP, EDX, ECX,
@ -221,7 +222,7 @@ const int *FPURegCache::GetAllocationOrder(int &count)
static const int allocationOrder[] = static const int allocationOrder[] =
{ {
#ifdef _M_X64 #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 #elif _M_IX86
XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
#endif #endif

View File

@ -160,7 +160,7 @@
{ {
case 32: case 32:
accessSize = 32; accessSize = 32;
if(Core::g_CoreStartupParameter.bJITLoadStorelwzOff) {Default(inst); return;} if (Core::g_CoreStartupParameter.bJITLoadStorelwzOff) {Default(inst); return;}
break; //lwz break; //lwz
case 40: accessSize = 16; break; //lhz case 40: accessSize = 16; break; //lhz
case 34: accessSize = 8; break; //lbz case 34: accessSize = 8; break; //lbz

View File

@ -716,7 +716,7 @@ struct RegInfo {
} }
private: private:
RegInfo(RegInfo&); // DO NOT IMPLEMENT RegInfo(RegInfo&); // DO NOT IMPLEMENT
}; };
static void regMarkUse(RegInfo& R, InstLoc I, InstLoc Op, unsigned OpNum) { 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... // 64-bit - calling conventions differ between linux & windows, so...
#ifdef _WIN32 #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 #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 #endif
static const int RegAllocSize = sizeof(RegAllocOrder) / sizeof(X64Reg); 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}; 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) { static void regSpillCallerSaved(RegInfo& RI) {
#ifdef _M_IX86
// 32-bit
regSpill(RI, EDX); regSpill(RI, EDX);
regSpill(RI, ECX); regSpill(RI, ECX);
regSpill(RI, EAX); 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) { static X64Reg regUReg(RegInfo& RI, InstLoc I) {
@ -998,6 +1011,7 @@ static void regClearDeadMemAddress(RegInfo& RI, InstLoc I, InstLoc AI, unsigned
regClearInst(RI, AddrBase); regClearInst(RI, AddrBase);
} }
// in 64-bit build, this returns a completely bizarre address sometimes!
static OpArg regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI, static OpArg regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI,
unsigned OpNum, unsigned Size, X64Reg* dest, unsigned OpNum, unsigned Size, X64Reg* dest,
bool Profiled, bool Profiled,
@ -1015,7 +1029,7 @@ static OpArg regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI,
#else #else
// 64-bit // 64-bit
if (Profiled) if (Profiled)
return M((void*)((u8*)Memory::base + addr)); return MDisp(RBX, addr);
return M((void*)addr); return M((void*)addr);
#endif #endif
} }
@ -1030,6 +1044,7 @@ static OpArg regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI,
AddrBase = AI; AddrBase = AI;
} }
X64Reg baseReg; X64Reg baseReg;
// Ok, this stuff needs a comment or three :P -ector
if (RI.IInfo[I - RI.FirstI] & (2 << OpNum)) { if (RI.IInfo[I - RI.FirstI] & (2 << OpNum)) {
baseReg = regEnsureInReg(RI, AddrBase); baseReg = regEnsureInReg(RI, AddrBase);
regClearInst(RI, AddrBase); regClearInst(RI, AddrBase);
@ -1053,7 +1068,7 @@ static OpArg regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI,
#ifdef _M_IX86 #ifdef _M_IX86
return MDisp(baseReg, (u32)Memory::base + offset + ProfileOffset); return MDisp(baseReg, (u32)Memory::base + offset + ProfileOffset);
#else #else
return MDisp(RBX, offset + ProfileOffset); return MComplex(RBX, baseReg, 1, offset + ProfileOffset);
#endif #endif
} }
return MDisp(baseReg, offset); return MDisp(baseReg, offset);

View File

@ -204,9 +204,9 @@ const int *GPRRegCache::GetAllocationOrder(int &count)
{ {
#ifdef _M_X64 #ifdef _M_X64
#ifdef _WIN32 #ifdef _WIN32
RSI, RDI, R12, R13, R14, R8, R9, R10, R11 //, RCX RSI, RDI, R13, R14, R8, R9, R10, R11 //, RCX
#else #else
RBP, R12, R13, R14, R8, R9, R10, R11, //, RCX RBP, R13, R14, R8, R9, R10, R11, //, RCX
#endif #endif
#elif _M_IX86 #elif _M_IX86
ESI, EDI, EBX, EBP, EDX, ECX, ESI, EDI, EBX, EBP, EDX, ECX,