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 fmrx(UGeckoInstruction inst);
void cmpXi(UGeckoInstruction inst);
void cmpX(UGeckoInstruction inst);
void cmpXX(UGeckoInstruction inst);
void cntlzwx(UGeckoInstruction inst);

View File

@ -147,7 +147,7 @@ namespace Jit64
*/
// unsigned
void cmpXi(UGeckoInstruction inst)
void cmpXX(UGeckoInstruction inst)
{
// USES_CR
#ifdef JIT_OFF_OPTIONS
@ -159,21 +159,40 @@ namespace Jit64
// towards branches.
INSTRUCTION_START;
int a = inst.RA;
int b = inst.RB;
int crf = inst.CRFD;
int shift = crf * 4;
Gen::CCFlags less_than, greater_than;
OpArg comparand;
if (inst.OPCD == 10) {
less_than = CC_B;
greater_than = CC_A;
comparand = Imm32(inst.UIMM);
} else {
less_than = CC_L;
greater_than = CC_G;
comparand = Imm32((s32)(s16)inst.UIMM);
if (inst.OPCD == 31) {
gpr.Lock(a, b);
gpr.LoadToX64(a, true, false);
comparand = gpr.R(b);
if (inst.SUBOP10 == 32) {
//cmpl
less_than = CC_B;
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);
FixupBranch pLesser = J_CC(less_than);
FixupBranch pGreater = J_CC(greater_than);
@ -190,53 +209,13 @@ namespace Jit64
SetJumpTarget(continue1);
SetJumpTarget(continue2);
gpr.UnlockAll();
// 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.
// 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)
{
#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}},
{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}},
{11, Interpreter::cmpi, Jit64::cmpXi, {"cmpi", 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::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}},
{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}},
@ -283,8 +283,8 @@ GekkoOPTemplate table31[] =
{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}},
{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}},
{32, Interpreter::cmpl, Jit64::cmpX, {"cmpl", 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::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}},
{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}},

View File

@ -143,7 +143,7 @@ inline u32 GetCRBit(int bit) {
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) {
PowerPC::ppcState.cr = new_cr;
PowerPC::ExpandCR();