Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #527 from delroth/flags-opt
[RFC] PowerPC flags emulation optimization
  • Loading branch information
lioncash committed Jul 31, 2014
2 parents f507827 + fda2190 commit 5bb9a74
Show file tree
Hide file tree
Showing 40 changed files with 931 additions and 3,302 deletions.
1 change: 0 additions & 1 deletion Source/Android/res/values-ja/strings.xml
Expand Up @@ -137,7 +137,6 @@
<string name="jit64_recompiler">JIT64 Recompiler</string>
<string name="jitil_recompiler">JITIL Recompiler</string>
<string name="jit_arm_recompiler">JIT ARM Recompiler</string>
<string name="jitil_arm_recompiler">JITIL ARM Recompiler</string>
<string name="cpu_settings">CPU</string>
<string name="cpu_core">CPUコア</string>
<string name="cpu_core_desc">%s</string>
Expand Down
2 changes: 0 additions & 2 deletions Source/Android/res/values/arrays.xml
Expand Up @@ -19,12 +19,10 @@
<string-array name="emuCoreEntriesARM" translatable="false">
<item>@string/interpreter</item>
<item>@string/jit_arm_recompiler</item>
<item>@string/jitil_arm_recompiler</item>
</string-array>
<string-array name="emuCoreValuesARM" translatable="false">
<item>0</item>
<item>3</item>
<item>4</item>
</string-array>

<!-- CPU core selection - Other -->
Expand Down
1 change: 0 additions & 1 deletion Source/Android/res/values/strings.xml
Expand Up @@ -138,7 +138,6 @@
<string name="jit64_recompiler">JIT64 Recompiler</string>
<string name="jitil_recompiler">JITIL Recompiler</string>
<string name="jit_arm_recompiler">JIT ARM Recompiler</string>
<string name="jitil_arm_recompiler">JITIL ARM Recompiler</string>
<string name="cpu_settings">CPU</string>
<string name="cpu_core">CPU Core</string>
<string name="cpu_core_desc">%s</string>
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Common/x64Emitter.cpp
Expand Up @@ -721,7 +721,7 @@ void XEmitter::SETcc(CCFlags flag, OpArg dest)
{
if (dest.IsImm()) _assert_msg_(DYNA_REC, 0, "SETcc - Imm argument");
dest.operandReg = 0;
dest.WriteRex(this, 0, 0);
dest.WriteRex(this, 0, 8);
Write8(0x0F);
Write8(0x90 + (u8)flag);
dest.WriteRest(this);
Expand Down
6 changes: 0 additions & 6 deletions Source/Core/Core/CMakeLists.txt
Expand Up @@ -218,12 +218,6 @@ if(_M_ARM_32)
PowerPC/JitArm32/JitArm_LoadStorePaired.cpp
PowerPC/JitArm32/JitArm_SystemRegisters.cpp
PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp
#JitArmIL
PowerPC/JitArmIL/JitIL.cpp
PowerPC/JitArmIL/JitILAsm.cpp
PowerPC/JitArmIL/JitIL_Tables.cpp
PowerPC/JitArmIL/JitIL_Branch.cpp
PowerPC/JitArmIL/IR_Arm.cpp
)
endif()

Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp
Expand Up @@ -84,7 +84,7 @@ static void Trace(UGeckoInstruction& instCode)
char ppcInst[256];
DisassembleGekko(instCode.hex, PC, ppcInst, 256);

DEBUG_LOG(POWERPC, "INTER PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s %08x %s", PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3], PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), fregs.c_str(), instCode.hex, ppcInst);
DEBUG_LOG(POWERPC, "INTER PC: %08x SRR0: %08x SRR1: %08x CRval: %016lx FPSCR: %08x MSR: %08x LR: %08x %s %08x %s", PC, SRR0, SRR1, PowerPC::ppcState.cr_val[0], PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), instCode.hex, ppcInst);
}

int Interpreter::SingleStepInner(void)
Expand Down
36 changes: 13 additions & 23 deletions Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp
Expand Up @@ -4,32 +4,22 @@

#include "Core/PowerPC/Interpreter/Interpreter.h"

void Interpreter::Helper_UpdateCR0(u32 _uValue)
{
u32 new_cr0;
int sValue = (int)_uValue;
if (sValue > 0)
new_cr0 = 0x4;
else if (sValue < 0)
new_cr0 = 0x8;
else
new_cr0 = 0x2;
new_cr0 |= GetXER_SO();
SetCRField(0, new_cr0);
void Interpreter::Helper_UpdateCR0(u32 value)
{
s64 sign_extended = (s64)(s32)value;
u64 cr_val = (u64)sign_extended;
cr_val = (cr_val & ~(1ull << 61)) | ((u64)GetXER_SO() << 61);

PowerPC::ppcState.cr_val[0] = cr_val;
}

void Interpreter::Helper_UpdateCRx(int _x, u32 _uValue)
void Interpreter::Helper_UpdateCRx(int idx, u32 value)
{
u32 new_crX;
int sValue = (int)_uValue;
if (sValue > 0)
new_crX = 0x4;
else if (sValue < 0)
new_crX = 0x8;
else
new_crX = 0x2;
new_crX |= GetXER_SO();
SetCRField(_x, new_crX);
s64 sign_extended = (s64)(s32)value;
u64 cr_val = (u64)sign_extended;
cr_val = (cr_val & ~(1ull << 61)) | ((u64)GetXER_SO() << 61);

PowerPC::ppcState.cr_val[idx] = cr_val;
}

u32 Interpreter::Helper_Carry(u32 _uValue1, u32 _uValue2)
Expand Down
6 changes: 2 additions & 4 deletions Source/Core/Core/PowerPC/Jit64/Jit.cpp
Expand Up @@ -377,10 +377,8 @@ void Jit64::Trace()
}
#endif

DEBUG_LOG(DYNA_REC, "JIT64 PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s",
PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3],
PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr,
PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), fregs.c_str());
DEBUG_LOG(DYNA_REC, "JIT64 PC: %08x SRR0: %08x SRR1: %08x FPSCR: %08x MSR: %08x LR: %08x %s %s",
PC, SRR0, SRR1, PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), fregs.c_str());
}

void STACKALIGN Jit64::Jit(u32 em_address)
Expand Down
10 changes: 10 additions & 0 deletions Source/Core/Core/PowerPC/Jit64/Jit.h
Expand Up @@ -106,6 +106,16 @@ class Jit64 : public Jitx86Base
void GenerateRC();
void ComputeRC(const Gen::OpArg & arg);

// Reads a given bit of a given CR register part. Clobbers ABI_PARAM1,
// don't forget to xlock it before.
void GetCRFieldBit(int field, int bit, Gen::X64Reg out);
// Clobbers ABI_PARAM1 and ABI_PARAM2, xlock them before.
void SetCRFieldBit(int field, int bit, Gen::X64Reg in);

// Generates a branch that will check if a given bit of a CR register part
// is set or not.
FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set = true);

void tri_op(int d, int a, int b, bool reversible, void (XEmitter::*op)(Gen::X64Reg, Gen::OpArg));
typedef u32 (*Operation)(u32 a, u32 b);
void regimmop(int d, int a, bool binary, u32 value, Operation doop, void (XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&), bool Rc = false, bool carry = false);
Expand Down
24 changes: 6 additions & 18 deletions Source/Core/Core/PowerPC/Jit64/Jit_Branch.cpp
Expand Up @@ -117,11 +117,8 @@ void Jit64::bcx(UGeckoInstruction inst)
FixupBranch pConditionDontBranch;
if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) // Test a CR bit
{
TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3)));
if (inst.BO & BO_BRANCH_IF_TRUE) // Conditional branch
pConditionDontBranch = J_CC(CC_Z, true);
else
pConditionDontBranch = J_CC(CC_NZ, true);
pConditionDontBranch = JumpIfCRFieldBit(inst.BI >> 2, 3 - (inst.BI & 3),
!(inst.BO_2 & BO_BRANCH_IF_TRUE));
}

if (inst.LK)
Expand Down Expand Up @@ -179,14 +176,8 @@ void Jit64::bcctrx(UGeckoInstruction inst)
// BO_2 == 001zy -> b if false
// BO_2 == 011zy -> b if true

// Ripped from bclrx
TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3)));
Gen::CCFlags branch;
if (inst.BO_2 & BO_BRANCH_IF_TRUE)
branch = CC_Z;
else
branch = CC_NZ;
FixupBranch b = J_CC(branch, true);
FixupBranch b = JumpIfCRFieldBit(inst.BI >> 2, 3 - (inst.BI & 3),
!(inst.BO_2 & BO_BRANCH_IF_TRUE));
MOV(32, R(EAX), M(&CTR));
AND(32, R(EAX), Imm32(0xFFFFFFFC));
//MOV(32, M(&PC), R(EAX)); => Already done in WriteExitDestInEAX()
Expand Down Expand Up @@ -222,11 +213,8 @@ void Jit64::bclrx(UGeckoInstruction inst)
FixupBranch pConditionDontBranch;
if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) // Test a CR bit
{
TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3)));
if (inst.BO & BO_BRANCH_IF_TRUE) // Conditional branch
pConditionDontBranch = J_CC(CC_Z, true);
else
pConditionDontBranch = J_CC(CC_NZ, true);
pConditionDontBranch = JumpIfCRFieldBit(inst.BI >> 2, 3 - (inst.BI & 3),
!(inst.BO_2 & BO_BRANCH_IF_TRUE));
}

// This below line can be used to prove that blr "eats flags" in practice.
Expand Down
13 changes: 5 additions & 8 deletions Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp
Expand Up @@ -237,26 +237,22 @@ void Jit64::fcmpx(UGeckoInstruction inst)
pGreater = J_CC(CC_B);
}

// Equal
MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x2));
MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_EQ)));
continue1 = J();

// NAN
SetJumpTarget(pNaN);
MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x1));
MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_SO)));

if (a != b)
{
continue2 = J();

// Greater Than
SetJumpTarget(pGreater);
MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x4));
MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_GT)));
continue3 = J();

// Less Than
SetJumpTarget(pLesser);
MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x8));
MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_LT)));
}

SetJumpTarget(continue1);
Expand All @@ -266,6 +262,7 @@ void Jit64::fcmpx(UGeckoInstruction inst)
SetJumpTarget(continue3);
}

MOV(64, M(&PowerPC::ppcState.cr_val[crf]), R(RAX));
fpr.UnlockAll();
}

Expand Down

0 comments on commit 5bb9a74

Please sign in to comment.