Consolidate all jit integer compare ops into one function.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1550 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-12-15 21:05:37 +00:00
parent a44c421d01
commit 060523a805
4 changed files with 37 additions and 59 deletions

View File

@ -143,8 +143,7 @@ namespace Jit64
void fcmpx(UGeckoInstruction inst); void fcmpx(UGeckoInstruction inst);
void fmrx(UGeckoInstruction inst); void fmrx(UGeckoInstruction inst);
void cmpXi(UGeckoInstruction inst); void cmpXX(UGeckoInstruction inst);
void cmpX(UGeckoInstruction inst);
void cntlzwx(UGeckoInstruction inst); void cntlzwx(UGeckoInstruction inst);

View File

@ -147,7 +147,7 @@ namespace Jit64
*/ */
// unsigned // unsigned
void cmpXi(UGeckoInstruction inst) void cmpXX(UGeckoInstruction inst)
{ {
// USES_CR // USES_CR
#ifdef JIT_OFF_OPTIONS #ifdef JIT_OFF_OPTIONS
@ -159,21 +159,40 @@ namespace Jit64
// towards branches. // towards branches.
INSTRUCTION_START; INSTRUCTION_START;
int a = inst.RA; int a = inst.RA;
int b = inst.RB;
int crf = inst.CRFD; int crf = inst.CRFD;
int shift = crf * 4; int shift = crf * 4;
Gen::CCFlags less_than, greater_than; Gen::CCFlags less_than, greater_than;
OpArg comparand; OpArg comparand;
if (inst.OPCD == 10) { if (inst.OPCD == 31) {
less_than = CC_B; gpr.Lock(a, b);
greater_than = CC_A; gpr.LoadToX64(a, true, false);
comparand = Imm32(inst.UIMM); comparand = gpr.R(b);
} else { if (inst.SUBOP10 == 32) {
less_than = CC_L; //cmpl
greater_than = CC_G; less_than = CC_B;
comparand = Imm32((s32)(s16)inst.UIMM); greater_than = CC_A;
} else {
//cmp
less_than = CC_L;
greater_than = CC_G;
}
}
else {
gpr.KillImmediate(a); // todo, optimize instead, but unlikely to make a difference
if (inst.OPCD == 10) {
//cmpli
less_than = CC_B;
greater_than = CC_A;
comparand = Imm32(inst.UIMM);
} else if (inst.OPCD == 11) {
//cmpi
less_than = CC_L;
greater_than = CC_G;
comparand = Imm32((s32)(s16)inst.UIMM);
}
} }
gpr.KillImmediate(a); // todo, optimize instead, but unlikely to make a difference
CMP(32, gpr.R(a), comparand); CMP(32, gpr.R(a), comparand);
FixupBranch pLesser = J_CC(less_than); FixupBranch pLesser = J_CC(less_than);
FixupBranch pGreater = J_CC(greater_than); FixupBranch pGreater = J_CC(greater_than);
@ -190,53 +209,13 @@ namespace Jit64
SetJumpTarget(continue1); SetJumpTarget(continue1);
SetJumpTarget(continue2); SetJumpTarget(continue2);
gpr.UnlockAll();
// TODO: Add extra code at the end for the "taken" case. Jump to it from the matching branches. // TODO: Add extra code at the end for the "taken" case. Jump to it from the matching branches.
// Since it's the last block, some liberties can be taken. // Since it's the last block, some liberties can be taken.
// don't forget to flush registers AFTER the cmp BEFORE the jmp. Flushing doesn't affect flags. // don't forget to flush registers AFTER the cmp BEFORE the jmp. Flushing doesn't affect flags.
} }
// signed
void cmpX(UGeckoInstruction inst)
{
// USES_CR
#ifdef JIT_OFF_OPTIONS
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITIntegerOff)
{Default(inst); return;} // turn off from debugger
#endif
INSTRUCTION_START;
int a = inst.RA;
int b = inst.RB;
int crf = inst.CRFD;
int shift = crf * 4;
Gen::CCFlags less_than, greater_than;
Gen::OpArg comparand = gpr.R(b);
if (inst.SUBOP10 == 32) {
less_than = CC_B;
greater_than = CC_A;
} else {
less_than = CC_L;
greater_than = CC_G;
}
gpr.Lock(a, b);
gpr.LoadToX64(a, true, false);
CMP(32, gpr.R(a), comparand);
FixupBranch pLesser = J_CC(less_than);
FixupBranch pGreater = J_CC(greater_than);
// _x86Reg == 0
MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x2)); // _x86Reg == 0
FixupBranch continue1 = J();
SetJumpTarget(pGreater);
MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x4)); // _x86Reg > 0
FixupBranch continue2 = J();
SetJumpTarget(pLesser);
MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x8)); // _x86Reg < 0
SetJumpTarget(continue1);
SetJumpTarget(continue2);
gpr.UnlockAll();
}
void orx(UGeckoInstruction inst) void orx(UGeckoInstruction inst)
{ {
#ifdef JIT_OFF_OPTIONS #ifdef JIT_OFF_OPTIONS

View File

@ -141,8 +141,8 @@ GekkoOPTemplate primarytable[] =
{7, Interpreter::mulli, Jit64::mulli, {"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}}, {7, Interpreter::mulli, Jit64::mulli, {"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}},
{8, Interpreter::subfic, Jit64::subfic, {"subfic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}}, {8, Interpreter::subfic, Jit64::subfic, {"subfic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}},
{10, Interpreter::cmpli, Jit64::cmpXi, {"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, {10, Interpreter::cmpli, Jit64::cmpXX, {"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}},
{11, Interpreter::cmpi, Jit64::cmpXi, {"cmpi", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, {11, Interpreter::cmpi, Jit64::cmpXX, {"cmpi", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}},
{12, Interpreter::addic, Jit64::reg_imm, {"addic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}}, {12, Interpreter::addic, Jit64::reg_imm, {"addic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}},
{13, Interpreter::addic_rc, Jit64::reg_imm, {"addic_rc", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CR0}}, {13, Interpreter::addic_rc, Jit64::reg_imm, {"addic_rc", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CR0}},
{14, Interpreter::addi, Jit64::reg_imm, {"addi", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}}, {14, Interpreter::addi, Jit64::reg_imm, {"addi", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}},
@ -283,8 +283,8 @@ GekkoOPTemplate table31[] =
{412, Interpreter::orcx, Jit64::Default, {"orcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, {412, Interpreter::orcx, Jit64::Default, {"orcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
{476, Interpreter::nandx, Jit64::Default, {"nandx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, {476, Interpreter::nandx, Jit64::Default, {"nandx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
{284, Interpreter::eqvx, Jit64::Default, {"eqvx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, {284, Interpreter::eqvx, Jit64::Default, {"eqvx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
{0, Interpreter::cmp, Jit64::cmpX, {"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, {0, Interpreter::cmp, Jit64::cmpXX, {"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
{32, Interpreter::cmpl, Jit64::cmpX, {"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, {32, Interpreter::cmpl, Jit64::cmpXX, {"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
{26, Interpreter::cntlzwx, Jit64::cntlzwx, {"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, {26, Interpreter::cntlzwx, Jit64::cntlzwx, {"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
{922, Interpreter::extshx, Jit64::extshx, {"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, {922, Interpreter::extshx, Jit64::extshx, {"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
{954, Interpreter::extsbx, Jit64::extsbx, {"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, {954, Interpreter::extsbx, Jit64::extsbx, {"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},

View File

@ -143,7 +143,7 @@ inline u32 GetCRBit(int bit) {
return (PowerPC::ppcState.cr_fast[bit >> 2] >> (3 - (bit & 3))) & 1; return (PowerPC::ppcState.cr_fast[bit >> 2] >> (3 - (bit & 3))) & 1;
} }
// SetCR and GetCR may become fairly slow soon. Should be avoided if possible. // SetCR and GetCR are fairly slow. Should be avoided if possible.
inline void SetCR(u32 new_cr) { inline void SetCR(u32 new_cr) {
PowerPC::ppcState.cr = new_cr; PowerPC::ppcState.cr = new_cr;
PowerPC::ExpandCR(); PowerPC::ExpandCR();