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:
parent
a44c421d01
commit
060523a805
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}},
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue