From 79cc000d6298782a38a5bb0969e07960df438264 Mon Sep 17 00:00:00 2001 From: magumagu Date: Mon, 23 Jun 2014 20:34:03 -0700 Subject: [PATCH] JITIL: Optimize compare instruction. --- Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp | 80 +++++++++++-------- Source/Core/Core/PowerPC/JitILCommon/IR.cpp | 64 --------------- .../PowerPC/JitILCommon/JitILBase_Integer.cpp | 4 +- 3 files changed, 50 insertions(+), 98 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp index 8abe9fd3f9..e87d24ff76 100644 --- a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp @@ -550,6 +550,48 @@ static void regEmitICmpInst(RegInfo& RI, InstLoc I, CCFlags flag) { regNormalRegClear(RI, I); } +static void regEmitICmpCRInst(RegInfo& RI, InstLoc I) { + bool signed_compare = getOpcode(*I) == ICmpCRSigned; + X64Reg reg; + if (RI.IInfo[I - RI.FirstI] & 4) + { + reg = regEnsureInReg(RI, getOp1(I)); + if (signed_compare) + RI.Jit->MOVSX(64, 32, reg, R(reg)); + } + else + { + reg = regFindFreeReg(RI); + if (signed_compare) + RI.Jit->MOVSX(64, 32, reg, regLocForInst(RI, getOp1(I))); + else + RI.Jit->MOV(32, R(reg), regLocForInst(RI, getOp1(I))); + } + if (isImm(*getOp2(I))) + { + unsigned RHS = RI.Build->GetImmValue(getOp2(I)); + if (!signed_compare && (RHS & 0x80000000U)) + { + RI.Jit->MOV(32, R(EAX), Imm32(RHS)); + RI.Jit->SUB(64, R(reg), R(RAX)); + } + else if (RHS) + { + RI.Jit->SUB(64, R(reg), Imm32(RHS)); + } + } + else + { + if (signed_compare) + RI.Jit->MOVSX(64, 32, RAX, regLocForInst(RI, getOp2(I))); + else + RI.Jit->MOV(32, R(EAX), regLocForInst(RI, getOp2(I))); + RI.Jit->SUB(64, R(reg), R(RAX)); + } + RI.regs[reg] = I; + regNormalRegClear(RI, I); +} + static void regWriteExit(RegInfo& RI, InstLoc dest) { if (isImm(*dest)) { RI.exitNumber++; @@ -1077,42 +1119,16 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) { regEmitICmpInst(RI, I, CC_LE); break; } - case ICmpCRUnsigned: { + case ICmpCRUnsigned: + { if (!thisUsed) break; - regEmitCmp(RI, I); - X64Reg reg = regBinReg(RI, I); - FixupBranch pLesser = Jit->J_CC(CC_B); - FixupBranch pGreater = Jit->J_CC(CC_A); - Jit->MOV(32, R(reg), Imm32(0x2)); // _x86Reg == 0 - FixupBranch continue1 = Jit->J(); - Jit->SetJumpTarget(pGreater); - Jit->MOV(32, R(reg), Imm32(0x4)); // _x86Reg > 0 - FixupBranch continue2 = Jit->J(); - Jit->SetJumpTarget(pLesser); - Jit->MOV(32, R(reg), Imm32(0x8)); // _x86Reg < 0 - Jit->SetJumpTarget(continue1); - Jit->SetJumpTarget(continue2); - RI.regs[reg] = I; - regNormalRegClear(RI, I); + regEmitICmpCRInst(RI, I); break; } - case ICmpCRSigned: { + case ICmpCRSigned: + { if (!thisUsed) break; - regEmitCmp(RI, I); - X64Reg reg = regBinReg(RI, I); - FixupBranch pLesser = Jit->J_CC(CC_L); - FixupBranch pGreater = Jit->J_CC(CC_G); - Jit->MOV(32, R(reg), Imm32(0x2)); // _x86Reg == 0 - FixupBranch continue1 = Jit->J(); - Jit->SetJumpTarget(pGreater); - Jit->MOV(32, R(reg), Imm32(0x4)); // _x86Reg > 0 - FixupBranch continue2 = Jit->J(); - Jit->SetJumpTarget(pLesser); - Jit->MOV(32, R(reg), Imm32(0x8)); // _x86Reg < 0 - Jit->SetJumpTarget(continue1); - Jit->SetJumpTarget(continue2); - RI.regs[reg] = I; - regNormalRegClear(RI, I); + regEmitICmpCRInst(RI, I); break; } case ConvertFromFastCR: diff --git a/Source/Core/Core/PowerPC/JitILCommon/IR.cpp b/Source/Core/Core/PowerPC/JitILCommon/IR.cpp index 0f0bb1c7f3..032b953d3e 100644 --- a/Source/Core/Core/PowerPC/JitILCommon/IR.cpp +++ b/Source/Core/Core/PowerPC/JitILCommon/IR.cpp @@ -849,42 +849,6 @@ InstLoc IRBuilder::FoldBranchCond(InstLoc Op1, InstLoc Op2) { return EmitBranchUncond(Op2); return nullptr; } - if (getOpcode(*Op1) == And && - isImm(*getOp2(Op1)) && - getOpcode(*getOp1(Op1)) == ICmpCRSigned) { - unsigned branchValue = GetImmValue(getOp2(Op1)); - if (branchValue == 2) - return FoldBranchCond(EmitICmpEq(getOp1(getOp1(Op1)), - getOp2(getOp1(Op1))), Op2); - if (branchValue == 4) - return FoldBranchCond(EmitICmpSgt(getOp1(getOp1(Op1)), - getOp2(getOp1(Op1))), Op2); - if (branchValue == 8) - return FoldBranchCond(EmitICmpSlt(getOp1(getOp1(Op1)), - getOp2(getOp1(Op1))), Op2); - } - if (getOpcode(*Op1) == Xor && - isImm(*getOp2(Op1))) { - InstLoc XOp1 = getOp1(Op1); - unsigned branchValue = GetImmValue(getOp2(Op1)); - if (getOpcode(*XOp1) == And && - isImm(*getOp2(XOp1)) && - getOpcode(*getOp1(XOp1)) == ICmpCRSigned) { - unsigned innerBranchValue = - GetImmValue(getOp2(XOp1)); - if (branchValue == innerBranchValue) { - if (branchValue == 2) - return FoldBranchCond(EmitICmpNe(getOp1(getOp1(XOp1)), - getOp2(getOp1(XOp1))), Op2); - if (branchValue == 4) - return FoldBranchCond(EmitICmpSle(getOp1(getOp1(XOp1)), - getOp2(getOp1(XOp1))), Op2); - if (branchValue == 8) - return FoldBranchCond(EmitICmpSge(getOp1(getOp1(XOp1)), - getOp2(getOp1(XOp1))), Op2); - } - } - } return EmitBiOp(BranchCond, Op1, Op2); } @@ -965,38 +929,10 @@ InstLoc IRBuilder::FoldICmp(unsigned Opcode, InstLoc Op1, InstLoc Op2) { } InstLoc IRBuilder::FoldICmpCRSigned(InstLoc Op1, InstLoc Op2) { - if (isImm(*Op1)) { - if (isImm(*Op2)) { - int c1 = (int)GetImmValue(Op1), - c2 = (int)GetImmValue(Op2), - result; - if (c1 == c2) - result = 2; - else if (c1 > c2) - result = 4; - else - result = 8; - return EmitIntConst(result); - } - } return EmitBiOp(ICmpCRSigned, Op1, Op2); } InstLoc IRBuilder::FoldICmpCRUnsigned(InstLoc Op1, InstLoc Op2) { - if (isImm(*Op1)) { - if (isImm(*Op2)) { - unsigned int c1 = GetImmValue(Op1), - c2 = GetImmValue(Op2), - result; - if (c1 == c2) - result = 2; - else if (c1 > c2) - result = 4; - else - result = 8; - return EmitIntConst(result); - } - } return EmitBiOp(ICmpCRUnsigned, Op1, Op2); } diff --git a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_Integer.cpp b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_Integer.cpp index 6f275184ee..e7b96a6850 100644 --- a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_Integer.cpp @@ -12,7 +12,7 @@ static void ComputeRC(IREmitter::IRBuilder& ibuild, IREmitter::InstLoc val) { IREmitter::InstLoc res = ibuild.EmitICmpCRSigned(val, ibuild.EmitIntConst(0)); - ibuild.EmitStoreCR(ibuild.EmitConvertToFastCR(res), 0); + ibuild.EmitStoreCR(res, 0); } void JitILBase::reg_imm(UGeckoInstruction inst) @@ -114,7 +114,7 @@ void JitILBase::cmpXX(UGeckoInstruction inst) js.downcountAmount++; //TODO: should this be somewhere else? - ibuild.EmitStoreCR(ibuild.EmitConvertToFastCR(res), inst.CRFD); + ibuild.EmitStoreCR(res, inst.CRFD); } void JitILBase::boolX(UGeckoInstruction inst)