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.
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);
}

View File

@ -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
}

View File

@ -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);}

View File

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

View File

@ -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

View File

@ -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];

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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,