diff options
| author | hrydgard <hrydgard@gmail.com> | 2008-07-16 20:50:16 +0000 |
|---|---|---|
| committer | hrydgard <hrydgard@gmail.com> | 2008-07-16 20:50:16 +0000 |
| commit | ea934759e15c94ad2fa67e76e11f5d469ebfccf4 (patch) | |
| tree | 43dd6f2fa6a3e747e0d81c602d5490d02b10b087 /Source/Core | |
| parent | cb5072c3e4cf66d33d30697984a9179534334b38 (diff) | |
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
Diffstat (limited to 'Source/Core')
21 files changed, 321 insertions, 223 deletions
diff --git a/Source/Core/Common/Common.vcproj b/Source/Core/Common/Common.vcproj index 02688ff4fe..7344e39587 100644 --- a/Source/Core/Common/Common.vcproj +++ b/Source/Core/Common/Common.vcproj @@ -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"
@@ -472,6 +472,14 @@ >
</File>
<File
+ RelativePath=".\Src\FileUtil.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Src\FileUtil.h"
+ >
+ </File>
+ <File
RelativePath=".\Src\Hash.cpp"
>
</File>
diff --git a/Source/Core/Common/Src/Common.h b/Source/Core/Common/Src/Common.h index d3f0fa481f..8281703c10 100644 --- a/Source/Core/Common/Src/Common.h +++ b/Source/Core/Common/Src/Common.h @@ -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
diff --git a/Source/Core/Common/Src/FileUtil.cpp b/Source/Core/Common/Src/FileUtil.cpp new file mode 100644 index 0000000000..1eb5540486 --- /dev/null +++ b/Source/Core/Common/Src/FileUtil.cpp @@ -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
+}
\ No newline at end of file diff --git a/Source/Core/Common/Src/FileUtil.h b/Source/Core/Common/Src/FileUtil.h new file mode 100644 index 0000000000..b170d45ba7 --- /dev/null +++ b/Source/Core/Common/Src/FileUtil.h @@ -0,0 +1,12 @@ +#ifndef _FILEUTIL_H
+#define _FILEUTIL_H
+
+#include <string>
+
+class File
+{
+public:
+ static bool Exists(const std::string &filename);
+};
+
+#endif
diff --git a/Source/Core/Common/Src/MemArena.cpp b/Source/Core/Common/Src/MemArena.cpp index f577373fdd..4455f99004 100644 --- a/Source/Core/Common/Src/MemArena.cpp +++ b/Source/Core/Common/Src/MemArena.cpp @@ -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
}
-
-
diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj index 1779e0bfd7..cc8922d284 100644 --- a/Source/Core/Core/Core.vcproj +++ b/Source/Core/Core/Core.vcproj @@ -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"
@@ -902,6 +902,14 @@ >
</File>
<File
+ RelativePath=".\Src\PowerPC\Jit64\JitBackpatch.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Src\PowerPC\Jit64\JitBackpatch.h"
+ >
+ </File>
+ <File
RelativePath=".\Src\PowerPC\Jit64\JitCache.cpp"
>
</File>
diff --git a/Source/Core/Core/Src/CoreTiming.cpp b/Source/Core/Core/Src/CoreTiming.cpp index eb31d9d46a..3799db6501 100644 --- a/Source/Core/Core/Src/CoreTiming.cpp +++ b/Source/Core/Core/Src/CoreTiming.cpp @@ -233,6 +233,7 @@ void Advance() if (!first)
{
LOG(GEKKO, "WARNING - no events in queue. Setting downcount to 10000");
+ // PanicAlert?
downcount += 10000;
}
else
diff --git a/Source/Core/Core/Src/MemTools.cpp b/Source/Core/Core/Src/MemTools.cpp index e9e091a14e..3bcad01b7b 100644 --- a/Source/Core/Core/Src/MemTools.cpp +++ b/Source/Core/Core/Src/MemTools.cpp @@ -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
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index ce258ffb7b..729fb5a033 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -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);
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp new file mode 100644 index 0000000000..b16d333b31 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp @@ -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
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h new file mode 100644 index 0000000000..1cf07196ab --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h @@ -0,0 +1,10 @@ +#ifndef _JITBACKPATCH_H
+#define _JITBACKPATCH_H
+
+#include "Common.h"
+
+namespace Jit64 {
+void BackPatch(u8 *codePtr, int accessType, u32 emAddress);
+}
+
+#endif
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp index c17e526afc..52040c5da0 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp @@ -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,20 +74,49 @@ namespace Jit64 LOG(DYNA_REC, "======================================");
}
+ void InitCache()
+ {
+ jo.optimizeStack = true;
+ 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;
+
+ codeCache = (u8*)AllocateExecutableMemory(CODE_SIZE);
+ genFunctions = (u8*)AllocateExecutableMemory(GEN_SIZE);
+ trampolineCache = (u8*)AllocateExecutableMemory(TRAMPOLINE_SIZE);
+ trampolineCodePtr = trampolineCache;
+ numFlushes = 0;
+
+ blocks = new JitBlock[MAX_NUM_BLOCKS];
+ blockCodePointers = new u8*[MAX_NUM_BLOCKS];
+ ClearCache();
+ SetCodePtr(genFunctions);
+ Asm::Generate();
+ // Protect the generated functions
+ WriteProtectMemory(genFunctions, 4096, true);
+ 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
@@ -98,50 +129,39 @@ namespace Jit64 return false;
}
- void LinkBlocksCallback(u64 userdata, int cyclesLate)
+ u8 *Jit(u32 emAddress)
{
- LinkBlocks();
- }
-
- u8 *Jit(u32 emaddress)
- {
- if (GetCodePtr() >= codeCache + CODE_SIZE - 0x10000 || numBlocks>=MAX_NUM_BLOCKS-1)
+ if (GetCodePtr() >= codeCache + CODE_SIZE - 0x10000 || numBlocks >= MAX_NUM_BLOCKS - 1)
{
- //PanicAlert("Cleared cache");
+ // PanicAlert("Cleared cache");
LOG(DYNA_REC, "JIT code cache full - clearing cache and restoring memory")
ClearCache();
}
JitBlock &b = blocks[numBlocks];
- b.originalAddress = emaddress;
+ 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;
- 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!
+ 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[0] != INVALID_EXIT)
- {
- unlinked[b.exitAddress[0]] = numBlocks;
+ if (b.exitAddress[i] != INVALID_EXIT) {
+ links_to.insert(std::pair<u32, int>(b.exitAddress[i], 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();
+
+ u8 *oldCodePtr = GetWritableCodePtr();
+ LinkBlock(numBlocks);
+ LinkBlockExits(numBlocks);
+ SetCodePtr(oldCodePtr);
}
numBlocks++; //commit the current block
return 0;
@@ -159,29 +179,6 @@ namespace Jit64 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.enableFastMem = true;
- jo.noAssumeFPLoadFromMem = false;
- jo.fpAccurateFlags = true;
-
- codeCache = (u8*)AllocateExecutableMemory(CODE_SIZE);
- genFunctions = (u8*)AllocateExecutableMemory(GEN_SIZE);
- trampolineCache = (u8*)AllocateExecutableMemory(TRAMPOLINE_SIZE);
- trampolineCodePtr = trampolineCache;
- numFlushes = 0;
-
- blocks = new JitBlock[MAX_NUM_BLOCKS];
- blockCodePointers = new u8*[MAX_NUM_BLOCKS];
- ClearCache();
- SetCodePtr(genFunctions);
- Asm::Generate();
- // Protect the generated functions
- WriteProtectMemory(genFunctions, 4096, true);
- SetCodePtr(codeCache);
- }
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
- }
- }
-
- 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);
+ 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);
}
- // 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);
- }
-
}
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp index b623e8aa01..8851c3d8eb 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp @@ -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;
}
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Paired.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Paired.cpp index aada348f42..52ef314a45 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Paired.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Paired.cpp @@ -23,6 +23,11 @@ #include "JitCache.h"
#include "JitRegCache.h"
+// TODO
+// ps_madds0
+// ps_muls0
+// ps_madds1
+
//#define OLD Default(inst); return;
#define OLD
diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp index a8ed96b2c0..74611d6791 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp @@ -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;
diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.h b/Source/Core/Core/Src/PowerPC/PowerPC.h index 38dda982fb..077b0b0e0d 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.h +++ b/Source/Core/Core/Src/PowerPC/PowerPC.h @@ -36,7 +36,7 @@ namespace PowerPC CORE_INTERPRETER,
CORE_DYNAREC,
};
- struct GC_ALIGNED16(PowerPCState)
+ struct GC_ALIGNED64(PowerPCState)
{
u32 mojs[128];
// sets of registers
diff --git a/Source/Core/DebuggerWX/DebuggerWX.vcproj b/Source/Core/DebuggerWX/DebuggerWX.vcproj index 4bf1ba00b5..4502ea779a 100644 --- a/Source/Core/DebuggerWX/DebuggerWX.vcproj +++ b/Source/Core/DebuggerWX/DebuggerWX.vcproj @@ -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"
diff --git a/Source/Core/DiscIO/DiscIO.vcproj b/Source/Core/DiscIO/DiscIO.vcproj index 345b8243ba..b5180b7ae2 100644 --- a/Source/Core/DiscIO/DiscIO.vcproj +++ b/Source/Core/DiscIO/DiscIO.vcproj @@ -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"
diff --git a/Source/Core/DolphinWX/DolphinWX.vcproj b/Source/Core/DolphinWX/DolphinWX.vcproj index fb622f0d42..1ab5715ba0 100644 --- a/Source/Core/DolphinWX/DolphinWX.vcproj +++ b/Source/Core/DolphinWX/DolphinWX.vcproj @@ -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"
diff --git a/Source/Core/DolphinWX/src/Main.cpp b/Source/Core/DolphinWX/src/Main.cpp index a278f8f8f9..4d9c18cdbe 100644 --- a/Source/Core/DolphinWX/src/Main.cpp +++ b/Source/Core/DolphinWX/src/Main.cpp @@ -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);
diff --git a/Source/Core/DolphinWX/src/PluginManager.cpp b/Source/Core/DolphinWX/src/PluginManager.cpp index 63bcb4ab24..07f7594bd7 100644 --- a/Source/Core/DolphinWX/src/PluginManager.cpp +++ b/Source/Core/DolphinWX/src/PluginManager.cpp @@ -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());
+ }
}
}
|
