Mostly cleanup and some better crash messages. Also enabled partial block linking (see JitCache.cpp), should give a small speedup but may cause problems, please report!

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@12 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard
2008-07-16 20:50:16 +00:00
parent cb5072c3e4
commit ea934759e1
28 changed files with 419 additions and 344 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Version="8.00"
Name="Common"
ProjectGUID="{C573CAF7-EE6A-458E-8049-16C0BF34C2E9}"
RootNamespace="Common"
@ -471,6 +471,14 @@
RelativePath=".\Src\DynamicLibrary.h"
>
</File>
<File
RelativePath=".\Src\FileUtil.cpp"
>
</File>
<File
RelativePath=".\Src\FileUtil.h"
>
</File>
<File
RelativePath=".\Src\Hash.cpp"
>

View File

@ -69,7 +69,9 @@ typedef signed __int16 s16;
typedef signed __int8 s8;
#define GC_ALIGNED16(x) __declspec(align(16)) x
#define GC_ALIGNED64(x) __declspec(align(64)) x
#define GC_ALIGNED16_DECL(x) __declspec(align(16)) x
#define GC_ALIGNED64_DECL(x) __declspec(align(64)) x
#else

View File

@ -0,0 +1,11 @@
#include "Common.h"
#include "FileUtil.h"
bool File::Exists(const std::string &filename)
{
#ifdef _WIN32
return GetFileAttributes(filename.c_str()) != INVALID_FILE_ATTRIBUTES;
#else
return true; //TODO
#endif
}

View File

@ -0,0 +1,12 @@
#ifndef _FILEUTIL_H
#define _FILEUTIL_H
#include <string>
class File
{
public:
static bool Exists(const std::string &filename);
};
#endif

View File

@ -104,11 +104,10 @@ u64 MemArena::Find4GBBase()
{
#ifdef _M_X64
#ifdef _WIN32
// The highest thing in any 1GB section of memory space is the locked cache. We only need to fit it.
// 64 bit
u8* base = (u8*)VirtualAlloc(0, 0xE1000000, MEM_RESERVE, PAGE_READWRITE);
VirtualFree(base, 0, MEM_RELEASE);
return((u64)base);
#else
// Very precarious - mmap cannot return an error when trying to map already used pages.
// This makes the Windows approach above unusable on Linux, so we will simply pray...
@ -116,12 +115,13 @@ u64 MemArena::Find4GBBase()
#endif
#else
// Only grab a bit less than 1GB
// 32 bit
// The highest thing in any 1GB section of memory space is the locked cache. We only need to fit it.
u8* base = (u8*)VirtualAlloc(0, 0x31000000, MEM_RESERVE, PAGE_READWRITE);
VirtualFree(base, 0, MEM_RELEASE);
if (base) {
VirtualFree(base, 0, MEM_RELEASE);
}
return((u64)base);
#endif
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Version="8.00"
Name="Core"
ProjectGUID="{F0B874CB-4476-4199-9315-8343D05AE684}"
RootNamespace="Core"
@ -901,6 +901,14 @@
RelativePath=".\Src\PowerPC\Jit64\JitAsm.h"
>
</File>
<File
RelativePath=".\Src\PowerPC\Jit64\JitBackpatch.cpp"
>
</File>
<File
RelativePath=".\Src\PowerPC\Jit64\JitBackpatch.h"
>
</File>
<File
RelativePath=".\Src\PowerPC\Jit64\JitCache.cpp"
>

View File

@ -233,6 +233,7 @@ void Advance()
if (!first)
{
LOG(GEKKO, "WARNING - no events in queue. Setting downcount to 10000");
// PanicAlert?
downcount += 10000;
}
else

View File

@ -24,12 +24,12 @@
#include <vector>
#include "Common.h"
#include "x64Analyzer.h"
#include "PowerPC/Jit64/Jit.h"
#include "MemTools.h"
#include "HW/Memmap.h"
#include "PowerPC/Jit64/Jit.h"
#include "PowerPC/Jit64/JitBackpatch.h"
#include "x64Analyzer.h"
//#ifdef ASDFKJLASJDF
namespace EMM
{
/* DESIGN
@ -98,14 +98,11 @@ struct Watch
std::vector<Watch> watches;
void UpdateProtection(EAddr startAddr, EAddr endAddr)
{
}
int AddWatchRegion(EAddr startAddr, EAddr endAddr, WR watchFor, WatchType type, WatchCallback callback, u64 userData)
{
static int watchIDGen = 0;
@ -124,8 +121,6 @@ int AddWatchRegion(EAddr startAddr, EAddr endAddr, WR watchFor, WatchType type,
return watch.ID;
}
void Notify(EAddr address, WR action)
{
for (std::vector<Watch>::iterator iter = watches.begin(); iter != watches.end(); ++iter)
@ -208,6 +203,9 @@ public:
}
};
// ======
// From here on is the code in this file that actually works and is active.
LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
{
switch (pPtrs->ExceptionRecord->ExceptionCode)
@ -233,6 +231,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
//Figure out what address was hit
DWORD_PTR badAddress = (DWORD_PTR)pPtrs->ExceptionRecord->ExceptionInformation[1];
//TODO: First examine the address, make sure it's within the emulated memory space
u64 memspaceBottom = (u64)Memory::base;
if (badAddress < memspaceBottom) {
PanicAlert("Exception handler - access below memory space. %08x%08x",
badAddress >> 32, badAddress);
@ -240,17 +239,15 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
u32 emAddress = (u32)(badAddress - memspaceBottom);
//Now we have the emulated address.
//_assert_msg_(DYNA_REC,0,"MT : %08x",emAddress);
//Let's notify everyone who wants to be notified
//Notify(emAddress, accessType == 0 ? Read : Write);
CONTEXT *ctx = pPtrs->ContextRecord;
//opportunity to change the debug regs!
//opportunity to play with the context - we can change the debug regs!
//We could emulate the memory accesses here, but then they would still be around to take up
//execution resources. Instead, we backpatch and retry.
Jit64::BackPatch(codePtr, accessType);
//execution resources. Instead, we backpatch into a generic memory call and retry.
Jit64::BackPatch(codePtr, accessType, emAddress);
// We no longer touch Rip, since we return back to the instruction, after overwriting it with a
// trampoline jump and some nops

View File

@ -14,6 +14,11 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
// Low hanging fruit:
// all used in zelda
// negx
#ifndef _JIT_H
#define _JIT_H
@ -74,7 +79,6 @@ namespace Jit64
void WriteExitDestInEAX(int exit_num);
void WriteExceptionExit(u32 exception);
void WriteRfiExitDestInEAX();
void BackPatch(u8 *codePtr, int accessType);
void HLEFunction(UGeckoInstruction _inst);

View File

@ -0,0 +1,126 @@
#include <string>
#include "Common.h"
#include "disasm.h"
#include "JitBackpatch.h"
#include "../../HW/Memmap.h"
#include "x64Emitter.h"
#include "x64Analyzer.h"
#include "StringUtil.h"
#include "Jit.h"
using namespace Gen;
namespace Jit64 {
extern u8 *trampolineCodePtr;
void BackPatchError(const std::string &text, u8 *codePtr, u32 emAddress) {
u64 code_addr = (u64)codePtr;
disassembler disasm;
char disbuf[256];
memset(disbuf, 0, 256);
#ifdef _M_IX86
disasm.disasm32(
#else
disasm.disasm64(
#endif
0, code_addr, codePtr, disbuf);
PanicAlert("%s\n\n"
"Error encountered accessing emulated address %08x.\n"
"Culprit instruction: \n%s\nat %08x%08x",
text.c_str(), emAddress, disbuf, code_addr>>32, code_addr);
return;
}
void BackPatch(u8 *codePtr, int accessType, u32 emAddress)
{
if (!IsInJitCode(codePtr))
return; // this will become a regular crash real soon after this
// TODO: also mark and remember the instruction address as known HW memory access, for use in later compiles.
// But to do that we need to be able to reconstruct what instruction wrote this code, and we can't do that yet.
u8 *oldCodePtr = GetWritableCodePtr();
InstructionInfo info;
if (!DisassembleMov(codePtr, info, accessType)) {
BackPatchError("BackPatch - failed to disassemble MOV instruction", codePtr, emAddress);
}
if (info.operandSize != 4) {
BackPatchError(StringFromFormat("BackPatch - no support for operand size %i", info.operandSize), codePtr, emAddress);
}
u64 code_addr = (u64)codePtr;
X64Reg addrReg = (X64Reg)info.scaledReg;
X64Reg dataReg = (X64Reg)info.regOperandReg;
if (info.otherReg != RBX)
PanicAlert("BackPatch : Base reg not RBX."
"\n\nAttempted to access %08x.", emAddress);
if (accessType == OP_ACCESS_WRITE)
PanicAlert("BackPatch : Currently only supporting reads."
"\n\nAttempted to write to %08x.", emAddress);
//if (info.instructionSize < 5)
// PanicAlert("Instruction at %08x Too Small : %i", (u32)codePtr, info.instructionSize);
// OK, let's write a trampoline, and a jump to it.
// Later, let's share trampolines.
// In the first iteration, we assume that all accesses are 32-bit. We also only deal with reads.
// Next step - support writes, special case FIFO writes. Also, support 32-bit mode.
u8 *trampoline = trampolineCodePtr;
SetCodePtr(trampolineCodePtr);
// * Save all volatile regs
PUSH(RCX);
PUSH(RDX);
PUSH(RSI);
PUSH(RDI);
PUSH(R8);
PUSH(R9);
PUSH(R10);
PUSH(R11);
//TODO: Also preserve XMM0-3?
SUB(64, R(RSP), Imm8(0x20));
// * Set up stack frame.
// * Call ReadMemory32
//LEA(32, ECX, MDisp((X64Reg)addrReg, info.displacement));
MOV(32, R(ECX), R((X64Reg)addrReg));
if (info.displacement) {
ADD(32, R(ECX), Imm32(info.displacement));
}
switch (info.operandSize) {
//case 1:
// CALL((void *)&Memory::Read_U8);
// break;
case 4:
CALL((void *)&Memory::Read_U32);
break;
default:
BackPatchError(StringFromFormat("We don't handle the size %i yet in backpatch", info.operandSize), codePtr, emAddress);
break;
}
// * Tear down stack frame.
ADD(64, R(RSP), Imm8(0x20));
POP(R11);
POP(R10);
POP(R9);
POP(R8);
POP(RDI);
POP(RSI);
POP(RDX);
POP(RCX);
MOV(32, R(dataReg), R(EAX));
RET();
trampolineCodePtr = GetWritableCodePtr();
SetCodePtr(codePtr);
int bswapNopCount;
// Check the following BSWAP for REX byte
if ((GetCodePtr()[info.instructionSize] & 0xF0) == 0x40)
bswapNopCount = 3;
else
bswapNopCount = 2;
CALL(trampoline);
NOP((int)info.instructionSize + bswapNopCount - 5);
SetCodePtr(oldCodePtr);
}
} // namespace

View File

@ -0,0 +1,10 @@
#ifndef _JITBACKPATCH_H
#define _JITBACKPATCH_H
#include "Common.h"
namespace Jit64 {
void BackPatch(u8 *codePtr, int accessType, u32 emAddress);
}
#endif

View File

@ -26,7 +26,6 @@
#include "../PPCTables.h"
#include "../PPCAnalyst.h"
#include "x64Emitter.h"
#include "x64Analyzer.h"
@ -34,6 +33,8 @@
#include "JitCache.h"
#include "JitAsm.h"
#include "disasm.h"
using namespace Gen;
namespace Jit64
@ -43,6 +44,8 @@ namespace Jit64
u8 *trampolineCache;
u8 *trampolineCodePtr;
#define INVALID_EXIT 0xFFFFFFFF
void LinkBlockExits(int i);
void LinkBlock(int i);
enum
{
@ -54,8 +57,7 @@ namespace Jit64
u8 **blockCodePointers; // cut these in half and force below 2GB?
// todo - replace with something faster
std::map<u32, int> unlinked;
std::multimap<u32, int> links_to;
JitBlock *blocks;
int numBlocks;
@ -72,98 +74,15 @@ namespace Jit64
LOG(DYNA_REC, "======================================");
}
JitBlock *CurBlock()
{
return &blocks[numBlocks];
}
JitBlock *GetBlock(int no)
{
return &blocks[no];
}
int GetNumBlocks()
{
return numBlocks;
}
bool RangeIntersect(int s1, int e1, int s2, int e2)
{
// check if any endpoint is inside the other range
if ( (s1 >= s2 && s1 <= e2) ||
(e1 >= s2 && e1 <= e2) ||
(s2 >= s1 && s2 <= e1) ||
(e2 >= s1 && e2 <= e1))
return true;
else
return false;
}
void LinkBlocksCallback(u64 userdata, int cyclesLate)
{
LinkBlocks();
}
u8 *Jit(u32 emaddress)
{
if (GetCodePtr() >= codeCache + CODE_SIZE - 0x10000 || numBlocks>=MAX_NUM_BLOCKS-1)
{
//PanicAlert("Cleared cache");
LOG(DYNA_REC, "JIT code cache full - clearing cache and restoring memory")
ClearCache();
}
JitBlock &b = blocks[numBlocks];
b.originalAddress = emaddress;
b.exitAddress[0] = INVALID_EXIT;
b.exitAddress[1] = INVALID_EXIT;
b.exitPtrs[0] = 0;
b.exitPtrs[1] = 0;
b.linkStatus[0] = false;
b.linkStatus[1] = false;
b.originalFirstOpcode = Memory::ReadFast32(emaddress);
blockCodePointers[numBlocks] = (u8*)DoJit(emaddress, b); //cast away const, evil
Memory::WriteUnchecked_U32((JIT_OPCODE << 26) | numBlocks, emaddress);
//Flatten should also compute exits
//Success!
if (jo.enableBlocklink) {
for (int i = 0; i < 2; i++) {
if (b.exitAddress[0] != INVALID_EXIT)
{
unlinked[b.exitAddress[0]] = numBlocks;
}
}
// Link max once per half billion cycles
//LinkBlocks();
/*if (!CoreTiming::IsScheduled(&LinkBlocksCallback))
{
CoreTiming::ScheduleEvent(50000000, &LinkBlocksCallback, "Link JIT blocks", 0);
}*/
//if ((numBlocks & 1) == 0)
LinkBlocks();
}
numBlocks++; //commit the current block
return 0;
}
void unknown_instruction(UGeckoInstruction _inst)
{
// CCPU::Break();
PanicAlert("unknown_instruction Jit64 - Fix me ;)");
_dbg_assert_(DYNA_REC, 0);
}
u8 **GetCodePointers()
{
return blockCodePointers;
}
void InitCache()
{
jo.optimizeStack = true;
jo.enableBlocklink = false; // Large speed boost but currently causes slowdowns too, due to stupid O(n^2) algo :P
jo.enableBlocklink = true; // Speed boost, but not 100% safe
#ifdef _M_X64
jo.enableFastMem = true;
#else
jo.enableFastMem = false;
#endif
jo.noAssumeFPLoadFromMem = false;
jo.fpAccurateFlags = true;
@ -183,6 +102,84 @@ namespace Jit64
SetCodePtr(codeCache);
}
JitBlock *CurBlock()
{
return &blocks[numBlocks];
}
JitBlock *GetBlock(int no)
{
return &blocks[no];
}
int GetNumBlocks()
{
return numBlocks;
}
bool RangeIntersect(int s1, int e1, int s2, int e2)
{
// check if any endpoint is inside the other range
if ( (s1 >= s2 && s1 <= e2) ||
(e1 >= s2 && e1 <= e2) ||
(s2 >= s1 && s2 <= e1) ||
(e2 >= s1 && e2 <= e1))
return true;
else
return false;
}
u8 *Jit(u32 emAddress)
{
if (GetCodePtr() >= codeCache + CODE_SIZE - 0x10000 || numBlocks >= MAX_NUM_BLOCKS - 1)
{
// PanicAlert("Cleared cache");
LOG(DYNA_REC, "JIT code cache full - clearing cache and restoring memory")
ClearCache();
}
JitBlock &b = blocks[numBlocks];
b.invalid = false;
b.originalAddress = emAddress;
b.originalFirstOpcode = Memory::ReadFast32(emAddress);
b.exitAddress[0] = INVALID_EXIT;
b.exitAddress[1] = INVALID_EXIT;
b.exitPtrs[0] = 0;
b.exitPtrs[1] = 0;
b.linkStatus[0] = false;
b.linkStatus[1] = false;
blockCodePointers[numBlocks] = (u8*)DoJit(emAddress, b); //cast away const
Memory::WriteUnchecked_U32((JIT_OPCODE << 26) | numBlocks, emAddress);
if (jo.enableBlocklink) {
for (int i = 0; i < 2; i++) {
if (b.exitAddress[i] != INVALID_EXIT) {
links_to.insert(std::pair<u32, int>(b.exitAddress[i], numBlocks));
}
}
u8 *oldCodePtr = GetWritableCodePtr();
LinkBlock(numBlocks);
LinkBlockExits(numBlocks);
SetCodePtr(oldCodePtr);
}
numBlocks++; //commit the current block
return 0;
}
void unknown_instruction(UGeckoInstruction _inst)
{
// CCPU::Break();
PanicAlert("unknown_instruction Jit64 - Fix me ;)");
_dbg_assert_(DYNA_REC, 0);
}
u8 **GetCodePointers()
{
return blockCodePointers;
}
bool IsInJitCode(u8 *codePtr) {
return codePtr >= codeCache && codePtr <= GetCodePtr();
}
@ -271,6 +268,11 @@ namespace Jit64
void LinkBlockExits(int i)
{
JitBlock &b = blocks[i];
if (b.invalid)
{
// This block is dead. Don't relink it.
return;
}
for (int e = 0; e < 2; e++)
{
if (b.exitAddress[e] != INVALID_EXIT && !b.linkStatus[e])
@ -286,37 +288,31 @@ namespace Jit64
}
}
/*
if ((b.exitAddress[0] == INVALID_EXIT || b.linkStatus[0]) &&
(b.exitAddress[1] == INVALID_EXIT || b.linkStatus[1])) {
unlinked.erase(iter);
if (unlinked.size() > 4000) PanicAlert("Removed from unlinked. Size = %i", unlinked.size());
}
*/
using namespace std;
void LinkBlock(int i)
{
LinkBlockExits(i);
JitBlock &b = blocks[i];
std::map<u32, int>::iterator iter;
iter = unlinked.find(b.originalAddress);
if (iter != unlinked.end())
{
LinkBlockExits(iter->second);
// todo - remove stuff from unlinked
pair<multimap<u32, int>::iterator, multimap<u32, int>::iterator> ppp;
// equal_range(b) returns pair<iterator,iterator> representing the range
// of element with key b
ppp = links_to.equal_range(b.originalAddress);
if (ppp.first == ppp.second)
return;
for (multimap<u32, int>::iterator iter2 = ppp.first; iter2 != ppp.second; ++iter2) {
// PanicAlert("Linking block %i to block %i", iter2->second, i);
LinkBlockExits(iter2->second);
}
}
void LinkBlocks()
{
u8 *oldCodePtr = GetWritableCodePtr();
//for (int i = 0; i < numBlocks; i++)
// LinkBlockExits(i);
for (std::map<u32, int>::iterator iter = unlinked.begin();
iter != unlinked.end(); iter++)
{
LinkBlockExits(iter->second);
}
// for (int i = 0; i < 2000; i++)
LinkBlock(numBlocks);
SetCodePtr(oldCodePtr);
}
void DestroyBlock(int blocknum, bool invalidate)
{
u32 codebytes = (JIT_OPCODE << 26) | blocknum; //generate from i
@ -336,6 +332,8 @@ namespace Jit64
//for something else, then it's fine.
LOG(MASTER_LOG, "WARNING - ClearCache detected code overwrite @ %08x", blocks[blocknum].originalAddress);
}
// TODO: Unlink block.
u8 *prev_code = GetWritableCodePtr();
// Spurious entrances from previously linked blocks can only come through checkedEntry
SetCodePtr((u8*)b.checkedEntry);
@ -344,7 +342,7 @@ namespace Jit64
SetCodePtr(blockCodePointers[blocknum]);
MOV(32, M(&PC), Imm32(b.originalAddress));
JMP(Asm::dispatcher, true);
SetCodePtr(prev_code);
SetCodePtr(prev_code); // reset code pointer
}
#define BLR_OP 0x4e800020
@ -358,7 +356,7 @@ namespace Jit64
for (int i = 0; i < numBlocks; i++)
{
if (RangeIntersect(blocks[i].originalAddress, blocks[i].originalAddress+blocks[i].originalSize,
address, address+length))
address, address + length))
{
DestroyBlock(i, true);
}
@ -368,11 +366,10 @@ namespace Jit64
void ClearCache()
{
// Is destroying the blocks really necessary?
for (int i = 0; i < numBlocks; i++)
{
for (int i = 0; i < numBlocks; i++) {
DestroyBlock(i, false);
}
unlinked.clear();
links_to.clear();
trampolineCodePtr = trampolineCache;
numBlocks = 0;
numFlushes++;
@ -381,96 +378,5 @@ namespace Jit64
SetCodePtr(codeCache);
}
extern u8 *trampolineCodePtr;
void BackPatch(u8 *codePtr, int accessType)
{
if (codePtr < codeCache || codePtr > codeCache + CODE_SIZE)
return; // this will become a regular crash real soon after this
static int counter = 0;
++counter;
if (counter == 30)
{
counter++;
counter--;
}
// TODO: also mark and remember the instruction address as known HW memory access, for use in later compiles.
// But to do that we need to be able to reconstruct what instruction wrote this code, and we can't do that yet.
u8 *oldCodePtr = GetWritableCodePtr();
InstructionInfo info;
if (!DisassembleMov(codePtr, info, accessType))
PanicAlert("BackPatch - failed to disassemble MOV instruction");
X64Reg addrReg = (X64Reg)info.scaledReg;
X64Reg dataReg = (X64Reg)info.regOperandReg;
if (info.otherReg != RBX)
PanicAlert("BackPatch : Base reg not RBX.");
if (accessType == OP_ACCESS_WRITE)
PanicAlert("BackPatch : Currently only supporting reads.");
//if (info.instructionSize < 5)
// PanicAlert("Instruction at %08x Too Small : %i", (u32)codePtr, info.instructionSize);
// OK, let's write a trampoline, and a jump to it.
// Later, let's share trampolines.
// In the first iteration, we assume that all accesses are 32-bit. We also only deal with reads.
u8 *trampoline = trampolineCodePtr;
SetCodePtr(trampolineCodePtr);
// * Save all volatile regs
PUSH(RCX);
PUSH(RDX);
PUSH(RSI);
PUSH(RDI);
PUSH(R8);
PUSH(R9);
PUSH(R10);
PUSH(R11);
//TODO: Also preserve XMM0-3?
SUB(64, R(RSP), Imm8(0x20));
// * Set up stack frame.
// * Call ReadMemory32
//LEA(32, ECX, MDisp((X64Reg)addrReg, info.displacement));
MOV(32, R(ECX), R((X64Reg)addrReg));
if (info.displacement) {
ADD(32, R(ECX), Imm32(info.displacement));
}
switch (info.operandSize) {
//case 1:
// CALL((void *)&Memory::Read_U8);
// break;
case 4:
CALL((void *)&Memory::Read_U32);
break;
default:
PanicAlert("We don't handle this size %i yet in backpatch", info.operandSize);
break;
}
// * Tear down stack frame.
ADD(64, R(RSP), Imm8(0x20));
POP(R11);
POP(R10);
POP(R9);
POP(R8);
POP(RDI);
POP(RSI);
POP(RDX);
POP(RCX);
MOV(32, R(dataReg), R(EAX));
RET();
trampolineCodePtr = GetWritableCodePtr();
SetCodePtr(codePtr);
int bswapNopCount;
// Check the following BSWAP for REX byte
if ((GetCodePtr()[info.instructionSize] & 0xF0) == 0x40)
bswapNopCount = 3;
else
bswapNopCount = 2;
CALL(trampoline);
NOP((int)info.instructionSize + bswapNopCount - 5);
// There is also a BSWAP to kill.
SetCodePtr(oldCodePtr);
}
}

View File

@ -44,21 +44,21 @@
namespace Jit64
{
#ifdef _M_X64
void SafeLoadECXtoEAX(int accessSize, int offset)
void SafeLoadECXtoEAX(int accessSize, s32 offset)
{
if (offset)
ADD(32,R(ECX),Imm32((u32)offset));
TEST(32,R(ECX),Imm32(0x0C000000));
ADD(32, R(ECX), Imm32((u32)offset));
TEST(32, R(ECX), Imm32(0x0C000000));
FixupBranch argh = J_CC(CC_NZ);
if (accessSize != 32)
XOR(32, R(EAX), R(EAX));
MOV(accessSize, R(EAX), MComplex(RBX, ECX, SCALE_1, 0));
if (accessSize == 32)
BSWAP(32,EAX);
BSWAP(32, EAX);
else if (accessSize == 16)
{
BSWAP(32,EAX);
SHR(32,R(EAX),Imm8(16));
BSWAP(32, EAX);
SHR(32, R(EAX), Imm8(16));
}
FixupBranch arg2 = J();
SetJumpTarget(argh);
@ -71,7 +71,7 @@ namespace Jit64
SetJumpTarget(arg2);
}
#elif _M_IX86
void SafeLoadECXtoEAX(int accessSize, int offset)
void SafeLoadECXtoEAX(int accessSize, s32 offset)
{
if (offset)
ADD(32, R(ECX), Imm32((u32)offset));
@ -86,7 +86,7 @@ namespace Jit64
BSWAP(32,EAX);
else if (accessSize == 16)
{
BSWAP(32,EAX);
BSWAP(32, EAX);
SHR(32, R(EAX), Imm8(16));
}
FixupBranch arg2 = J();
@ -183,10 +183,10 @@ namespace Jit64
// Safe and boring
gpr.Flush(FLUSH_VOLATILE);
gpr.Lock(d, a);
MOV(32,R(ECX), gpr.R(a));
MOV(32, R(ECX), gpr.R(a));
SafeLoadECXtoEAX(accessSize, offset);
gpr.LoadToX64(d, false, true);
MOV(32,gpr.R(d), R(EAX));
MOV(32, gpr.R(d), R(EAX));
gpr.UnlockAll();
return;
}

View File

@ -23,6 +23,11 @@
#include "JitCache.h"
#include "JitRegCache.h"
// TODO
// ps_madds0
// ps_muls0
// ps_madds1
//#define OLD Default(inst); return;
#define OLD

View File

@ -29,7 +29,8 @@
namespace PowerPC
{
GC_ALIGNED16_DECL(PowerPCState ppcState);
// align to cache line
GC_ALIGNED64_DECL(PowerPCState ppcState);
ICPUCore* m_pCore = NULL;
volatile CPUState state = CPU_STEPPING;

View File

@ -36,7 +36,7 @@ namespace PowerPC
CORE_INTERPRETER,
CORE_DYNAREC,
};
struct GC_ALIGNED16(PowerPCState)
struct GC_ALIGNED64(PowerPCState)
{
u32 mojs[128];
// sets of registers

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Version="8.00"
Name="DebuggerWX"
ProjectGUID="{4D3CD4C5-412B-4B49-9B1B-A68A2A129C77}"
RootNamespace="DebuggerWX"
@ -238,6 +238,7 @@
AdditionalIncludeDirectories="..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\Core\Src;;..\Common\Src"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;__WXMSW__"
RuntimeLibrary="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Version="8.00"
Name="DiscIO"
ProjectGUID="{B7F1A9FB-BEA8-416E-9460-AE35A6A5165C}"
RootNamespace="DiscIO"
@ -24,6 +24,7 @@
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
@ -88,6 +89,7 @@
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
@ -153,7 +155,7 @@
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
@ -215,7 +217,7 @@
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
@ -279,7 +281,7 @@
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
@ -341,7 +343,7 @@
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Version="8.00"
Name="DolphinWX"
ProjectGUID="{A72606EF-C5C1-4954-90AD-F0F93A8D97D9}"
RootNamespace="DolphinWX"
@ -157,9 +157,11 @@
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/EHsc "
Optimization="2"
Optimization="3"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="false"
AdditionalIncludeDirectories="..\Common\Src;..\Core\Src;..\DiscIO\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\DebuggerWX\src"
PreprocessorDefinitions="WIN32;__WXMSW__;_WINDOWS;NOPCH;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS"
StringPooling="true"

View File

@ -170,7 +170,6 @@ void Host_UpdateDisasmDialog()
{
wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_UPDATEDISASMDIALOG);
wxPostEvent(main_frame, event);
if (code_frame)
{
wxPostEvent(code_frame, event);

View File

@ -18,10 +18,11 @@
#include <string>
#include <vector>
#include "Globals.h"
#include "Common.h"
#include "PluginManager.h"
#include "Globals.h"
#include "FileSearch.h"
#include "FileUtil.h"
#include "PluginManager.h"
#include "StringUtil.h"
CPluginManager CPluginManager::m_Instance;
@ -57,7 +58,7 @@ CPluginManager::ScanForPlugins(wxWindow* _wxWindow)
{
wxProgressDialog dialog(_T("Scanning for Plugins"),
_T("Scanning..."),
rFilenames.size(), // range
(int)rFilenames.size(), // range
_wxWindow, // parent
wxPD_CAN_ABORT |
wxPD_APP_MODAL |
@ -67,8 +68,6 @@ CPluginManager::ScanForPlugins(wxWindow* _wxWindow)
wxPD_REMAINING_TIME |
wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small
);
dialog.CenterOnParent();
for (size_t i = 0; i < rFilenames.size(); i++)
@ -85,7 +84,7 @@ CPluginManager::ScanForPlugins(wxWindow* _wxWindow)
wxString msg;
msg.Printf("Scanning %s", FileName.c_str());
bool Cont = dialog.Update(i, msg);
bool Cont = dialog.Update((int)i, msg);
if (!Cont)
{
@ -154,7 +153,11 @@ CPluginInfo::CPluginInfo(const std::string& _rFileName)
}
else
{
PanicAlert("Failed to load plugin %s\nhello world", _rFileName.c_str());
if (!File::Exists(_rFileName)) {
PanicAlert("Could not load plugin %s - file does not exist", _rFileName.c_str());
} else {
PanicAlert("Failed to load plugin %s - unknown error.\n", _rFileName.c_str());
}
}
}