Skip to content

Commit

Permalink
Merge pull request #74 from Sonicadvance1/arbitrary-exit
Browse files Browse the repository at this point in the history
Arbitrary exits but actually fixed
  • Loading branch information
Parlane committed Feb 16, 2014
2 parents cbe7656 + 77851ed commit 96272c8
Show file tree
Hide file tree
Showing 19 changed files with 113 additions and 99 deletions.
35 changes: 19 additions & 16 deletions Source/Core/Core/PowerPC/Jit64/Jit.cpp
Expand Up @@ -276,31 +276,34 @@ void Jit64::Cleanup()
ABI_CallFunctionCCC((void *)&PowerPC::UpdatePerformanceMonitor, js.downcountAmount, jit->js.numLoadStoreInst, jit->js.numFloatingPointInst);
}

void Jit64::WriteExit(u32 destination, int exit_num)
void Jit64::WriteExit(u32 destination)
{
Cleanup();

SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));

//If nobody has taken care of this yet (this can be removed when all branches are done)
JitBlock *b = js.curBlock;
b->exitAddress[exit_num] = destination;
b->exitPtrs[exit_num] = GetWritableCodePtr();
JitBlock::LinkData linkData;
linkData.exitAddress = destination;
linkData.exitPtrs = GetWritableCodePtr();
linkData.linkStatus = false;

// Link opportunity!
if (jo.enableBlocklink)
int block;
if (jo.enableBlocklink && (block = blocks.GetBlockNumberFromStartAddress(destination)) >= 0)
{
int block = blocks.GetBlockNumberFromStartAddress(destination);
if (block >= 0)
{
// It exists! Joy of joy!
JMP(blocks.GetBlock(block)->checkedEntry, true);
b->linkStatus[exit_num] = true;
return;
}
// It exists! Joy of joy!
JMP(blocks.GetBlock(block)->checkedEntry, true);
linkData.linkStatus = true;
}
MOV(32, M(&PC), Imm32(destination));
JMP(asm_routines.dispatcher, true);
else
{
MOV(32, M(&PC), Imm32(destination));
JMP(asm_routines.dispatcher, true);
}

b->linkData.push_back(linkData);
}

void Jit64::WriteExitDestInEAX()
Expand Down Expand Up @@ -625,7 +628,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
FixupBranch noBreakpoint = J_CC(CC_Z);

WriteExit(ops[i].address, 0);
WriteExit(ops[i].address);
SetJumpTarget(noBreakpoint);
}

Expand Down Expand Up @@ -707,7 +710,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
{
gpr.Flush(FLUSH_ALL);
fpr.Flush(FLUSH_ALL);
WriteExit(nextPC, 0);
WriteExit(nextPC);
}

b->flags = js.block_flags;
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/PowerPC/Jit64/Jit.h
Expand Up @@ -88,7 +88,7 @@ class Jit64 : public Jitx86Base

// Utilities for use by opcodes

void WriteExit(u32 destination, int exit_num);
void WriteExit(u32 destination);
void WriteExitDestInEAX();
void WriteExceptionExit();
void WriteExternalExceptionExit();
Expand Down
10 changes: 5 additions & 5 deletions Source/Core/Core/PowerPC/Jit64/Jit_Branch.cpp
Expand Up @@ -91,7 +91,7 @@ void Jit64::bx(UGeckoInstruction inst)
// make idle loops go faster
js.downcountAmount += 8;
}
WriteExit(destination, 0);
WriteExit(destination);
}

// TODO - optimize to hell and beyond
Expand Down Expand Up @@ -136,13 +136,13 @@ void Jit64::bcx(UGeckoInstruction inst)
destination = SignExt16(inst.BD << 2);
else
destination = js.compilerPC + SignExt16(inst.BD << 2);
WriteExit(destination, 0);
WriteExit(destination);

if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0)
SetJumpTarget( pConditionDontBranch );
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
SetJumpTarget( pCTRDontBranch );
WriteExit(js.compilerPC + 4, 1);
WriteExit(js.compilerPC + 4);
}

void Jit64::bcctrx(UGeckoInstruction inst)
Expand Down Expand Up @@ -190,7 +190,7 @@ void Jit64::bcctrx(UGeckoInstruction inst)
WriteExitDestInEAX();
// Would really like to continue the block here, but it ends. TODO.
SetJumpTarget(b);
WriteExit(js.compilerPC + 4, 1);
WriteExit(js.compilerPC + 4);
}
}

Expand Down Expand Up @@ -245,5 +245,5 @@ void Jit64::bclrx(UGeckoInstruction inst)
SetJumpTarget( pConditionDontBranch );
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
SetJumpTarget( pCTRDontBranch );
WriteExit(js.compilerPC + 4, 1);
WriteExit(js.compilerPC + 4);
}
10 changes: 5 additions & 5 deletions Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
Expand Up @@ -400,7 +400,7 @@ void Jit64::cmpXX(UGeckoInstruction inst)
destination = SignExt16(js.next_inst.BD << 2);
else
destination = js.next_compilerPC + SignExt16(js.next_inst.BD << 2);
WriteExit(destination, 0);
WriteExit(destination);
}
else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 528)) // bcctrx
{
Expand All @@ -424,7 +424,7 @@ void Jit64::cmpXX(UGeckoInstruction inst)
}
else
{
WriteExit(js.next_compilerPC + 4, 0);
WriteExit(js.next_compilerPC + 4);
}

js.cancel = true;
Expand Down Expand Up @@ -507,7 +507,7 @@ void Jit64::cmpXX(UGeckoInstruction inst)
destination = SignExt16(js.next_inst.BD << 2);
else
destination = js.next_compilerPC + SignExt16(js.next_inst.BD << 2);
WriteExit(destination, 0);
WriteExit(destination);
}
else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 528)) // bcctrx
{
Expand All @@ -534,7 +534,7 @@ void Jit64::cmpXX(UGeckoInstruction inst)
if (!!(4 & test_bit) == condition) SetJumpTarget(continue2);
if (!!(2 & test_bit) == condition) SetJumpTarget(continue1);

WriteExit(js.next_compilerPC + 4, 1);
WriteExit(js.next_compilerPC + 4);

js.cancel = true;
}
Expand Down Expand Up @@ -2221,5 +2221,5 @@ void Jit64::twx(UGeckoInstruction inst)
SetJumpTarget(exit3);
SetJumpTarget(exit4);
SetJumpTarget(exit5);
WriteExit(js.compilerPC + 4, 1);
WriteExit(js.compilerPC + 4);
}
2 changes: 1 addition & 1 deletion Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
Expand Up @@ -480,5 +480,5 @@ void Jit64::stmw(UGeckoInstruction inst)
void Jit64::icbi(UGeckoInstruction inst)
{
Default(inst);
WriteExit(js.compilerPC + 4, 0);
WriteExit(js.compilerPC + 4);
}
2 changes: 1 addition & 1 deletion Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp
Expand Up @@ -125,7 +125,7 @@ void Jit64::mtmsr(UGeckoInstruction inst)
SetJumpTarget(noExceptionsPending);
SetJumpTarget(eeDisabled);

WriteExit(js.compilerPC + 4, 0);
WriteExit(js.compilerPC + 4);

js.firstFPInstructionFound = false;
}
Expand Down
13 changes: 7 additions & 6 deletions Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp
Expand Up @@ -554,7 +554,8 @@ static void regEmitICmpInst(RegInfo& RI, InstLoc I, CCFlags flag) {

static void regWriteExit(RegInfo& RI, InstLoc dest) {
if (isImm(*dest)) {
RI.Jit->WriteExit(RI.Build->GetImmValue(dest), RI.exitNumber++);
RI.exitNumber++;
RI.Jit->WriteExit(RI.Build->GetImmValue(dest));
} else {
RI.Jit->WriteExitDestInOpArg(regLocForInst(RI, dest));
}
Expand All @@ -566,7 +567,7 @@ static bool checkIsSNAN() {
return MathUtil::IsSNAN(isSNANTemp[0][0]) || MathUtil::IsSNAN(isSNANTemp[1][0]);
}

static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit) {
static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
//printf("Writing block: %x\n", js.blockStart);
RegInfo RI(Jit, ibuild->getFirstInst(), ibuild->getNumInsts());
RI.Build = ibuild;
Expand Down Expand Up @@ -1793,7 +1794,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit) {
Jit->ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckBreakPoints));
Jit->TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
FixupBranch noBreakpoint = Jit->J_CC(CC_Z);
Jit->WriteExit(InstLoc, 0);
Jit->WriteExit(InstLoc);
Jit->SetJumpTarget(noBreakpoint);
break;
}
Expand Down Expand Up @@ -1821,10 +1822,10 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit) {
}
}

Jit->WriteExit(jit->js.curBlock->exitAddress[0], 0);
Jit->WriteExit(exitAddress);
Jit->UD2();
}

void JitIL::WriteCode() {
DoWriteCode(&ibuild, this);
void JitIL::WriteCode(u32 exitAddress) {
DoWriteCode(&ibuild, this, exitAddress);
}
23 changes: 14 additions & 9 deletions Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp
Expand Up @@ -381,7 +381,7 @@ void JitIL::Cleanup()
ABI_CallFunctionCCC((void *)&PowerPC::UpdatePerformanceMonitor, js.downcountAmount, jit->js.numLoadStoreInst, jit->js.numFloatingPointInst);
}

void JitIL::WriteExit(u32 destination, int exit_num)
void JitIL::WriteExit(u32 destination)
{
Cleanup();
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
Expand All @@ -391,22 +391,25 @@ void JitIL::WriteExit(u32 destination, int exit_num)

//If nobody has taken care of this yet (this can be removed when all branches are done)
JitBlock *b = js.curBlock;
b->exitAddress[exit_num] = destination;
b->exitPtrs[exit_num] = GetWritableCodePtr();
JitBlock::LinkData linkData;
linkData.exitAddress = destination;
linkData.exitPtrs = GetWritableCodePtr();
linkData.linkStatus = false;

// Link opportunity!
int block = blocks.GetBlockNumberFromStartAddress(destination);
if (block >= 0 && jo.enableBlocklink)
int block;
if (jo.enableBlocklink && (block = blocks.GetBlockNumberFromStartAddress(destination)) >= 0)
{
// It exists! Joy of joy!
JMP(blocks.GetBlock(block)->checkedEntry, true);
b->linkStatus[exit_num] = true;
linkData.linkStatus = true;
}
else
{
MOV(32, M(&PC), Imm32(destination));
JMP(asm_routines.dispatcher, true);
}
b->linkData.push_back(linkData);
}

void JitIL::WriteExitDestInOpArg(const Gen::OpArg& arg)
Expand Down Expand Up @@ -541,14 +544,16 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc

// Analyze the block, collect all instructions it is made of (including inlining,
// if that is enabled), reorder instructions for optimal performance, and join joinable instructions.
b->exitAddress[0] = em_address;
u32 exitAddress = em_address;

u32 merged_addresses[32];
const int capacity_of_merged_addresses = sizeof(merged_addresses) / sizeof(merged_addresses[0]);
int size_of_merged_addresses = 0;
if (!memory_exception)
{
// If there is a memory exception inside a block (broken_block==true), compile up to that instruction.
b->exitAddress[0] = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize, merged_addresses, capacity_of_merged_addresses, size_of_merged_addresses);
// TODO
exitAddress = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize, merged_addresses, capacity_of_merged_addresses, size_of_merged_addresses);
}
PPCAnalyst::CodeOp *ops = code_buf->codebuffer;

Expand Down Expand Up @@ -707,7 +712,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
}

// Perform actual code generation
WriteCode();
WriteCode(exitAddress);

b->codeSize = (u32)(GetCodePtr() - normalEntry);
b->originalSize = size;
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Core/PowerPC/Jit64IL/JitIL.h
Expand Up @@ -95,7 +95,7 @@ class JitIL : public JitILBase, public EmuCodeBlock

// Utilities for use by opcodes

void WriteExit(u32 destination, int exit_num);
void WriteExit(u32 destination);
void WriteExitDestInOpArg(const Gen::OpArg& arg);
void WriteExceptionExit();
void WriteRfiExitDestInOpArg(const Gen::OpArg& arg);
Expand All @@ -111,7 +111,7 @@ class JitIL : public JitILBase, public EmuCodeBlock
void regimmop(int d, int a, bool binary, u32 value, Operation doop, void (Gen::XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&), bool Rc = false, bool carry = false);
void fp_tri_op(int d, int a, int b, bool reversible, bool dupe, void (Gen::XEmitter::*op)(Gen::X64Reg, Gen::OpArg));

void WriteCode();
void WriteCode(u32 exitAddress);

// OPCODES
void unknown_instruction(UGeckoInstruction _inst) override;
Expand Down
18 changes: 11 additions & 7 deletions Source/Core/Core/PowerPC/JitArm32/Jit.cpp
Expand Up @@ -186,23 +186,25 @@ void JitArm::WriteExceptionExit()
MOVI2R(A, (u32)asm_routines.testExceptions);
B(A);
}
void JitArm::WriteExit(u32 destination, int exit_num)
void JitArm::WriteExit(u32 destination)
{
Cleanup();

DoDownCount();
//If nobody has taken care of this yet (this can be removed when all branches are done)
JitBlock *b = js.curBlock;
b->exitAddress[exit_num] = destination;
b->exitPtrs[exit_num] = GetWritableCodePtr();
JitBlock::LinkData linkData;
linkData.exitAddress = destination;
linkData.exitPtrs = GetWritableCodePtr();
linkData.linkStatus = false;

// Link opportunity!
int block = blocks.GetBlockNumberFromStartAddress(destination);
if (block >= 0 && jo.enableBlocklink)
int block;
if (jo.enableBlocklink && (block = blocks.GetBlockNumberFromStartAddress(destination)) >= 0)
{
// It exists! Joy of joy!
B(blocks.GetBlock(block)->checkedEntry);
b->linkStatus[exit_num] = true;
linkData.linkStatus = true;
}
else
{
Expand All @@ -212,6 +214,8 @@ void JitArm::WriteExit(u32 destination, int exit_num)
MOVI2R(A, (u32)asm_routines.dispatcher);
B(A);
}

b->linkData.push_back(linkData);
}

void STACKALIGN JitArm::Run()
Expand Down Expand Up @@ -496,7 +500,7 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo
if (broken_block)
{
printf("Broken Block going to 0x%08x\n", nextPC);
WriteExit(nextPC, 0);
WriteExit(nextPC);
}

b->flags = js.block_flags;
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/PowerPC/JitArm32/Jit.h
Expand Up @@ -101,7 +101,7 @@ class JitArm : public JitBase, public ArmGen::ARMXCodeBlock

// Utilities for use by opcodes

void WriteExit(u32 destination, int exit_num);
void WriteExit(u32 destination);
void WriteExitDestInR(ARMReg Reg);
void WriteRfiExitDestInR(ARMReg Reg);
void WriteExceptionExit();
Expand Down

0 comments on commit 96272c8

Please sign in to comment.