small code cleanup in JIT: use JITIL's nice JITDISABLE macro

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4477 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman
2009-10-29 04:40:26 +00:00
parent 31e61da40d
commit 5b4d12c1f3
9 changed files with 1788 additions and 1867 deletions
+4 -1
View File
@@ -77,7 +77,10 @@ void Jit(u32 em_address);
// #define INSTRUCTION_START PPCTables::CountInstruction(inst);
#define INSTRUCTION_START
#define JITDISABLE(type) \
if (Core::g_CoreStartupParameter.bJITOff || \
Core::g_CoreStartupParameter.bJIT##type##Off) \
{Default(inst); return;}
class TrampolineCache : public Gen::XCodeBlock
{
@@ -73,9 +73,8 @@ void Jit64::fp_tri_op(int d, int a, int b, bool reversible, bool dupe, void (XEm
void Jit64::fp_arith_s(UGeckoInstruction inst)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITFloatingPointOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
INSTRUCTION_START
JITDISABLE(FloatingPoint)
if (inst.Rc) {
Default(inst); return;
}
@@ -104,9 +103,8 @@ void Jit64::fp_arith_s(UGeckoInstruction inst)
void Jit64::fmaddXX(UGeckoInstruction inst)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITFloatingPointOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
INSTRUCTION_START
JITDISABLE(FloatingPoint)
if (inst.Rc) {
Default(inst); return;
}
@@ -162,9 +160,8 @@ void Jit64::fmaddXX(UGeckoInstruction inst)
void Jit64::fsign(UGeckoInstruction inst)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITFloatingPointOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
INSTRUCTION_START
JITDISABLE(FloatingPoint)
if (inst.Rc) {
Default(inst); return;
}
@@ -195,8 +192,7 @@ void Jit64::fsign(UGeckoInstruction inst)
void Jit64::fmrx(UGeckoInstruction inst)
{
INSTRUCTION_START
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITFloatingPointOff)
{Default(inst); return;} // turn off from debugger
JITDISABLE(FloatingPoint)
if (inst.Rc) {
Default(inst); return;
}
@@ -213,9 +209,9 @@ void Jit64::fcmpx(UGeckoInstruction inst)
{
// TODO : This still causes crashes in Nights, and broken graphics
// in Paper Mario, Super Paper Mario as well as SoulCalibur 2 prolly others too.. :(
INSTRUCTION_START;
if(Core::g_CoreStartupParameter.bJITOff || jo.fpAccurateFcmp
|| Core::g_CoreStartupParameter.bJITFloatingPointOff) {
INSTRUCTION_START
JITDISABLE(FloatingPoint)
if (jo.fpAccurateFcmp) {
Default(inst); return; // turn off from debugger
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -51,9 +51,8 @@ u32 GC_ALIGNED16(temp32);
void Jit64::lfs(UGeckoInstruction inst)
{
if (Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
INSTRUCTION_START
JITDISABLE(LoadStoreFloating)
int d = inst.RD;
int a = inst.RA;
@@ -88,9 +87,8 @@ void Jit64::lfs(UGeckoInstruction inst)
void Jit64::lfd(UGeckoInstruction inst)
{
if (Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
INSTRUCTION_START
JITDISABLE(LoadStoreFloating)
int d = inst.RD;
int a = inst.RA;
@@ -155,10 +153,8 @@ void Jit64::lfd(UGeckoInstruction inst)
void Jit64::stfd(UGeckoInstruction inst)
{
if (Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
INSTRUCTION_START
JITDISABLE(LoadStoreFloating)
int s = inst.RS;
int a = inst.RA;
@@ -234,9 +230,8 @@ void Jit64::stfd(UGeckoInstruction inst)
void Jit64::stfs(UGeckoInstruction inst)
{
if (Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
INSTRUCTION_START
JITDISABLE(LoadStoreFloating)
bool update = inst.OPCD & 1;
int s = inst.RS;
@@ -291,9 +286,8 @@ void Jit64::stfs(UGeckoInstruction inst)
void Jit64::stfsx(UGeckoInstruction inst)
{
if (Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
INSTRUCTION_START
JITDISABLE(LoadStoreFloating)
// We can take a shortcut here - it's not likely that a hardware access would use this instruction.
gpr.FlushLockX(ABI_PARAM1);
@@ -311,9 +305,8 @@ void Jit64::stfsx(UGeckoInstruction inst)
void Jit64::lfsx(UGeckoInstruction inst)
{
if (Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
INSTRUCTION_START
JITDISABLE(LoadStoreFloating)
fpr.Lock(inst.RS);
fpr.LoadToX64(inst.RS, false, true);
@@ -91,9 +91,8 @@ const double GC_ALIGNED16(m_dequantizeTableD[]) =
// We will have to break block after quantizers are written to.
void Jit64::psq_st(UGeckoInstruction inst)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStorePairedOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
INSTRUCTION_START
JITDISABLE(LoadStorePaired)
js.block_flags |= BLOCK_USE_GQR0 << inst.I;
if (js.blockSetsQuantizers || !Core::GetStartupParameter().bOptimizeQuantizers)
@@ -296,9 +295,8 @@ void Jit64::psq_st(UGeckoInstruction inst)
void Jit64::psq_l(UGeckoInstruction inst)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStorePairedOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
INSTRUCTION_START
JITDISABLE(LoadStorePaired)
js.block_flags |= BLOCK_USE_GQR0 << inst.I;
File diff suppressed because it is too large Load Diff
@@ -29,172 +29,165 @@
#include "Jit.h"
#include "JitRegCache.h"
void Jit64::mtspr(UGeckoInstruction inst)
void Jit64::mtspr(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(SystemRegisters)
u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
int d = inst.RD;
switch (iIndex)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITSystemRegistersOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
int d = inst.RD;
case SPR_LR:
case SPR_CTR:
case SPR_XER:
// These are safe to do the easy way, see the bottom of this function.
break;
switch (iIndex)
case SPR_GQR0:
case SPR_GQR0 + 1:
case SPR_GQR0 + 2:
case SPR_GQR0 + 3:
case SPR_GQR0 + 4:
case SPR_GQR0 + 5:
case SPR_GQR0 + 6:
case SPR_GQR0 + 7:
js.blockSetsQuantizers = true;
// Prevent recompiler from compiling in old quantizer values.
// If the value changed, destroy all blocks using this quantizer
// This will create a little bit of block churn, but hopefully not too bad.
{
case SPR_LR:
case SPR_CTR:
case SPR_XER:
// These are safe to do the easy way, see the bottom of this function.
break;
case SPR_GQR0:
case SPR_GQR0 + 1:
case SPR_GQR0 + 2:
case SPR_GQR0 + 3:
case SPR_GQR0 + 4:
case SPR_GQR0 + 5:
case SPR_GQR0 + 6:
case SPR_GQR0 + 7:
js.blockSetsQuantizers = true;
// Prevent recompiler from compiling in old quantizer values.
// If the value changed, destroy all blocks using this quantizer
// This will create a little bit of block churn, but hopefully not too bad.
{
/*
/*
MOV(32, R(EAX), M(&PowerPC::ppcState.spr[iIndex])); // Load old value
CMP(32, R(EAX), gpr.R(inst.RD));
FixupBranch skip_destroy = J_CC(CC_E, false);
int gqr = iIndex - SPR_GQR0;
ABI_CallFunctionC(ProtectFunction(&Jit64::DestroyBlocksWithFlag, 1), (u32)BLOCK_USE_GQR0 << gqr);
SetJumpTarget(skip_destroy);*/
}
break;
}
break;
// TODO - break block if quantizers are written to.
default:
Default(inst);
return;
}
default:
Default(inst);
return;
}
// OK, this is easy.
// OK, this is easy.
gpr.Lock(d);
gpr.LoadToX64(d, true);
MOV(32, M(&PowerPC::ppcState.spr[iIndex]), gpr.R(d));
gpr.UnlockAll();
}
void Jit64::mfspr(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(SystemRegisters)
u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
int d = inst.RD;
switch (iIndex)
{
case SPR_WPAR:
Default(inst);
return;
// case SPR_DEC:
//MessageBox(NULL, "Read from DEC", "????", MB_OK);
//break;
case SPR_TL:
case SPR_TU:
//CALL((void Jit64::*)&CoreTiming::Advance);
// fall through
default:
gpr.Lock(d);
gpr.LoadToX64(d, true);
MOV(32, M(&PowerPC::ppcState.spr[iIndex]), gpr.R(d));
gpr.LoadToX64(d, false);
MOV(32, gpr.R(d), M(&PowerPC::ppcState.spr[iIndex]));
gpr.UnlockAll();
break;
}
void Jit64::mfspr(UGeckoInstruction inst)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITSystemRegistersOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
int d = inst.RD;
switch (iIndex)
{
case SPR_WPAR:
Default(inst);
return;
// case SPR_DEC:
//MessageBox(NULL, "Read from DEC", "????", MB_OK);
//break;
case SPR_TL:
case SPR_TU:
//CALL((void Jit64::*)&CoreTiming::Advance);
// fall through
default:
gpr.Lock(d);
gpr.LoadToX64(d, false);
MOV(32, gpr.R(d), M(&PowerPC::ppcState.spr[iIndex]));
gpr.UnlockAll();
break;
}
}
}
// =======================================================================================
// Don't interpret this, if we do we get thrown out
// --------------
void Jit64::mtmsr(UGeckoInstruction inst)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITSystemRegistersOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
gpr.LoadToX64(inst.RS, true, false);
MOV(32, M(&MSR), gpr.R(inst.RS));
gpr.Flush(FLUSH_ALL);
fpr.Flush(FLUSH_ALL);
WriteExit(js.compilerPC + 4, 0);
}
// ==============
// =======================================================================================
// Don't interpret this, if we do we get thrown out
// --------------
void Jit64::mtmsr(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(SystemRegisters)
gpr.LoadToX64(inst.RS, true, false);
MOV(32, M(&MSR), gpr.R(inst.RS));
gpr.Flush(FLUSH_ALL);
fpr.Flush(FLUSH_ALL);
WriteExit(js.compilerPC + 4, 0);
}
// ==============
void Jit64::mfmsr(UGeckoInstruction inst)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITSystemRegistersOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
//Privileged?
gpr.LoadToX64(inst.RD, false);
MOV(32, gpr.R(inst.RD), M(&MSR));
}
void Jit64::mfmsr(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(SystemRegisters)
//Privileged?
gpr.LoadToX64(inst.RD, false);
MOV(32, gpr.R(inst.RD), M(&MSR));
}
void Jit64::mftb(UGeckoInstruction inst)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITSystemRegistersOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
mfspr(inst);
}
void Jit64::mftb(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(SystemRegisters)
mfspr(inst);
}
void Jit64::mfcr(UGeckoInstruction inst)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITSystemRegistersOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
// USES_CR
int d = inst.RD;
gpr.LoadToX64(d, false, true);
MOV(8, R(EAX), M(&PowerPC::ppcState.cr_fast[0]));
void Jit64::mfcr(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(SystemRegisters)
// USES_CR
int d = inst.RD;
gpr.LoadToX64(d, false, true);
MOV(8, R(EAX), M(&PowerPC::ppcState.cr_fast[0]));
SHL(32, R(EAX), Imm8(4));
for (int i = 1; i < 7; i++) {
OR(8, R(EAX), M(&PowerPC::ppcState.cr_fast[i]));
SHL(32, R(EAX), Imm8(4));
for (int i = 1; i < 7; i++) {
OR(8, R(EAX), M(&PowerPC::ppcState.cr_fast[i]));
SHL(32, R(EAX), Imm8(4));
}
OR(8, R(EAX), M(&PowerPC::ppcState.cr_fast[7]));
MOV(32, gpr.R(d), R(EAX));
}
OR(8, R(EAX), M(&PowerPC::ppcState.cr_fast[7]));
MOV(32, gpr.R(d), R(EAX));
}
void Jit64::mtcrf(UGeckoInstruction inst)
{
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITSystemRegistersOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
void Jit64::mtcrf(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(SystemRegisters)
// USES_CR
u32 mask = 0;
u32 crm = inst.CRM;
if (crm == 0xFF) {
gpr.FlushLockX(ECX);
MOV(32, R(EAX), gpr.R(inst.RS));
for (int i = 0; i < 8; i++) {
MOV(32, R(ECX), R(EAX));
SHR(32, R(ECX), Imm8(28 - (i * 4)));
AND(32, R(ECX), Imm32(0xF));
MOV(8, M(&PowerPC::ppcState.cr_fast[i]), R(ECX));
}
gpr.UnlockAllX();
} else {
Default(inst);
return;
// TODO: translate this to work in new CR model.
for (int i = 0; i < 8; i++) {
if (crm & (1 << i))
mask |= 0xF << (i*4);
}
MOV(32, R(EAX), gpr.R(inst.RS));
MOV(32, R(ECX), M(&PowerPC::ppcState.cr));
AND(32, R(EAX), Imm32(mask));
AND(32, R(ECX), Imm32(~mask));
OR(32, R(EAX), R(ECX));
MOV(32, M(&PowerPC::ppcState.cr), R(EAX));
// USES_CR
u32 mask = 0;
u32 crm = inst.CRM;
if (crm == 0xFF) {
gpr.FlushLockX(ECX);
MOV(32, R(EAX), gpr.R(inst.RS));
for (int i = 0; i < 8; i++) {
MOV(32, R(ECX), R(EAX));
SHR(32, R(ECX), Imm8(28 - (i * 4)));
AND(32, R(ECX), Imm32(0xF));
MOV(8, M(&PowerPC::ppcState.cr_fast[i]), R(ECX));
}
gpr.UnlockAllX();
} else {
Default(inst);
return;
// TODO: translate this to work in new CR model.
for (int i = 0; i < 8; i++) {
if (crm & (1 << i))
mask |= 0xF << (i*4);
}
MOV(32, R(EAX), gpr.R(inst.RS));
MOV(32, R(ECX), M(&PowerPC::ppcState.cr));
AND(32, R(EAX), Imm32(mask));
AND(32, R(ECX), Imm32(~mask));
OR(32, R(EAX), R(ECX));
MOV(32, M(&PowerPC::ppcState.cr), R(EAX));
}
}
@@ -31,12 +31,12 @@
//#define INSTRUCTION_START Default(inst); return;
#define INSTRUCTION_START
void Jit64::mtspr(UGeckoInstruction inst)
{
INSTRUCTION_START
void Jit64::mtspr(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(SystemRegisters)
u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
switch(iIndex) {
switch(iIndex) {
case SPR_LR:
ibuild.EmitStoreLink(ibuild.EmitLoadGReg(inst.RD));
return;
@@ -60,121 +60,121 @@
default:
Default(inst);
return;
}
}
}
void Jit64::mfspr(UGeckoInstruction inst)
{
INSTRUCTION_START
void Jit64::mfspr(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(SystemRegisters)
u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
switch (iIndex)
{
case SPR_LR:
ibuild.EmitStoreGReg(ibuild.EmitLoadLink(), inst.RD);
return;
case SPR_CTR:
ibuild.EmitStoreGReg(ibuild.EmitLoadCTR(), inst.RD);
return;
case SPR_GQR0:
case SPR_GQR0 + 1:
case SPR_GQR0 + 2:
case SPR_GQR0 + 3:
case SPR_GQR0 + 4:
case SPR_GQR0 + 5:
case SPR_GQR0 + 6:
case SPR_GQR0 + 7:
ibuild.EmitStoreGReg(ibuild.EmitLoadGQR(iIndex - SPR_GQR0), inst.RD);
return;
default:
Default(inst);
return;
}
}
// =======================================================================================
// Don't interpret this, if we do we get thrown out
// --------------
void Jit64::mtmsr(UGeckoInstruction inst)
switch (iIndex)
{
ibuild.EmitStoreMSR(ibuild.EmitLoadGReg(inst.RS));
ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4));
case SPR_LR:
ibuild.EmitStoreGReg(ibuild.EmitLoadLink(), inst.RD);
return;
case SPR_CTR:
ibuild.EmitStoreGReg(ibuild.EmitLoadCTR(), inst.RD);
return;
case SPR_GQR0:
case SPR_GQR0 + 1:
case SPR_GQR0 + 2:
case SPR_GQR0 + 3:
case SPR_GQR0 + 4:
case SPR_GQR0 + 5:
case SPR_GQR0 + 6:
case SPR_GQR0 + 7:
ibuild.EmitStoreGReg(ibuild.EmitLoadGQR(iIndex - SPR_GQR0), inst.RD);
return;
default:
Default(inst);
return;
}
// ==============
}
void Jit64::mfmsr(UGeckoInstruction inst)
{
INSTRUCTION_START
// =======================================================================================
// Don't interpret this, if we do we get thrown out
// --------------
void Jit64::mtmsr(UGeckoInstruction inst)
{
ibuild.EmitStoreMSR(ibuild.EmitLoadGReg(inst.RS));
ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4));
}
// ==============
void Jit64::mfmsr(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(SystemRegisters)
ibuild.EmitStoreGReg(ibuild.EmitLoadMSR(), inst.RD);
}
}
void Jit64::mftb(UGeckoInstruction inst)
{
INSTRUCTION_START;
JITDISABLE(SystemRegisters)
void Jit64::mftb(UGeckoInstruction inst)
{
INSTRUCTION_START;
JITDISABLE(SystemRegisters)
mfspr(inst);
}
}
void Jit64::mfcr(UGeckoInstruction inst)
{
Default(inst); return;
void Jit64::mfcr(UGeckoInstruction inst)
{
Default(inst); return;
#if 0
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITSystemRegistersOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
// USES_CR
int d = inst.RD;
gpr.LoadToX64(d, false, true);
MOV(8, R(EAX), M(&PowerPC::ppcState.cr_fast[0]));
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITSystemRegistersOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
// USES_CR
int d = inst.RD;
gpr.LoadToX64(d, false, true);
MOV(8, R(EAX), M(&PowerPC::ppcState.cr_fast[0]));
SHL(32, R(EAX), Imm8(4));
for (int i = 1; i < 7; i++) {
OR(8, R(EAX), M(&PowerPC::ppcState.cr_fast[i]));
SHL(32, R(EAX), Imm8(4));
for (int i = 1; i < 7; i++) {
OR(8, R(EAX), M(&PowerPC::ppcState.cr_fast[i]));
SHL(32, R(EAX), Imm8(4));
}
OR(8, R(EAX), M(&PowerPC::ppcState.cr_fast[7]));
MOV(32, gpr.R(d), R(EAX));
#endif
}
OR(8, R(EAX), M(&PowerPC::ppcState.cr_fast[7]));
MOV(32, gpr.R(d), R(EAX));
#endif
}
void Jit64::mtcrf(UGeckoInstruction inst)
{
Default(inst); return;
void Jit64::mtcrf(UGeckoInstruction inst)
{
Default(inst); return;
#if 0
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITSystemRegistersOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITSystemRegistersOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
// USES_CR
u32 mask = 0;
u32 crm = inst.CRM;
if (crm == 0xFF) {
gpr.FlushLockX(ECX);
MOV(32, R(EAX), gpr.R(inst.RS));
for (int i = 0; i < 8; i++) {
MOV(32, R(ECX), R(EAX));
SHR(32, R(ECX), Imm8(28 - (i * 4)));
AND(32, R(ECX), Imm32(0xF));
MOV(8, M(&PowerPC::ppcState.cr_fast[i]), R(ECX));
}
gpr.UnlockAllX();
} else {
Default(inst);
return;
// TODO: translate this to work in new CR model.
for (int i = 0; i < 8; i++) {
if (crm & (1 << i))
mask |= 0xF << (i*4);
}
MOV(32, R(EAX), gpr.R(inst.RS));
MOV(32, R(ECX), M(&PowerPC::ppcState.cr));
AND(32, R(EAX), Imm32(mask));
AND(32, R(ECX), Imm32(~mask));
OR(32, R(EAX), R(ECX));
MOV(32, M(&PowerPC::ppcState.cr), R(EAX));
// USES_CR
u32 mask = 0;
u32 crm = inst.CRM;
if (crm == 0xFF) {
gpr.FlushLockX(ECX);
MOV(32, R(EAX), gpr.R(inst.RS));
for (int i = 0; i < 8; i++) {
MOV(32, R(ECX), R(EAX));
SHR(32, R(ECX), Imm8(28 - (i * 4)));
AND(32, R(ECX), Imm32(0xF));
MOV(8, M(&PowerPC::ppcState.cr_fast[i]), R(ECX));
}
#endif
gpr.UnlockAllX();
} else {
Default(inst);
return;
// TODO: translate this to work in new CR model.
for (int i = 0; i < 8; i++) {
if (crm & (1 << i))
mask |= 0xF << (i*4);
}
MOV(32, R(EAX), gpr.R(inst.RS));
MOV(32, R(ECX), M(&PowerPC::ppcState.cr));
AND(32, R(EAX), Imm32(mask));
AND(32, R(ECX), Imm32(~mask));
OR(32, R(EAX), R(ECX));
MOV(32, M(&PowerPC::ppcState.cr), R(EAX));
}
#endif
}