JitIL: A bit more constant folding, and a bit of cleanup.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2235 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
39b7fe10f7
commit
94ee9afdb2
|
@ -569,6 +569,42 @@ InstLoc IRBuilder::FoldICmp(unsigned Opcode, InstLoc Op1, InstLoc Op2) {
|
||||||
return EmitBiOp(Opcode, Op1, Op2);
|
return EmitBiOp(Opcode, Op1, 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);
|
||||||
|
}
|
||||||
|
|
||||||
InstLoc IRBuilder::FoldInterpreterFallback(InstLoc Op1, InstLoc Op2) {
|
InstLoc IRBuilder::FoldInterpreterFallback(InstLoc Op1, InstLoc Op2) {
|
||||||
for (unsigned i = 0; i < 32; i++) {
|
for (unsigned i = 0; i < 32; i++) {
|
||||||
GRegCache[i] = 0;
|
GRegCache[i] = 0;
|
||||||
|
@ -614,6 +650,8 @@ InstLoc IRBuilder::FoldBiOp(unsigned Opcode, InstLoc Op1, InstLoc Op2, unsigned
|
||||||
case ICmpUgt: case ICmpUlt: case ICmpUge: case ICmpUle:
|
case ICmpUgt: case ICmpUlt: case ICmpUge: case ICmpUle:
|
||||||
case ICmpSgt: case ICmpSlt: case ICmpSge: case ICmpSle:
|
case ICmpSgt: case ICmpSlt: case ICmpSge: case ICmpSle:
|
||||||
return FoldICmp(Opcode, Op1, Op2);
|
return FoldICmp(Opcode, Op1, Op2);
|
||||||
|
case ICmpCRSigned: return FoldICmpCRSigned(Op1, Op2);
|
||||||
|
case ICmpCRUnsigned: return FoldICmpCRUnsigned(Op1, Op2);
|
||||||
case InterpreterFallback: return FoldInterpreterFallback(Op1, Op2);
|
case InterpreterFallback: return FoldInterpreterFallback(Op1, Op2);
|
||||||
case FDMul: case FDAdd: case FDSub: return FoldDoubleBiOp(Opcode, Op1, Op2);
|
case FDMul: case FDAdd: case FDSub: return FoldDoubleBiOp(Opcode, Op1, Op2);
|
||||||
default: return EmitBiOp(Opcode, Op1, Op2, extra);
|
default: return EmitBiOp(Opcode, Op1, Op2, extra);
|
||||||
|
@ -966,7 +1004,7 @@ static OpArg regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI,
|
||||||
unsigned ProfileOffset = 0) {
|
unsigned ProfileOffset = 0) {
|
||||||
if (isImm(*AI)) {
|
if (isImm(*AI)) {
|
||||||
unsigned addr = RI.Build->GetImmValue(AI);
|
unsigned addr = RI.Build->GetImmValue(AI);
|
||||||
if (Memory::IsRAMAddress(addr)) {
|
if (Memory::IsRAMAddress(addr)) {
|
||||||
if (dest)
|
if (dest)
|
||||||
*dest = regFindFreeReg(RI);
|
*dest = regFindFreeReg(RI);
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
|
@ -1010,12 +1048,12 @@ static OpArg regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI,
|
||||||
baseReg = regEnsureInReg(RI, AddrBase);
|
baseReg = regEnsureInReg(RI, AddrBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Profiled) {
|
if (Profiled) {
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
return MDisp(baseReg, (u32)Memory::base + offset + ProfileOffset);
|
return MDisp(baseReg, (u32)Memory::base + offset + ProfileOffset);
|
||||||
#else
|
#else
|
||||||
// FIXME: TO IMPLEMENT (Profiled mode isn't the default,
|
// FIXME: TO IMPLEMENT (Profiled mode isn't the default,
|
||||||
// at least for the moment)
|
// at least for the moment)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return MDisp(baseReg, offset);
|
return MDisp(baseReg, offset);
|
||||||
|
@ -1232,7 +1270,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||||
case LoadCarry:
|
case LoadCarry:
|
||||||
case LoadCTR:
|
case LoadCTR:
|
||||||
case LoadMSR:
|
case LoadMSR:
|
||||||
case LoadFReg:
|
case LoadFReg:
|
||||||
case LoadGQR:
|
case LoadGQR:
|
||||||
case BlockEnd:
|
case BlockEnd:
|
||||||
case BlockStart:
|
case BlockStart:
|
||||||
|
@ -1269,7 +1307,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||||
break;
|
break;
|
||||||
case LoadDouble:
|
case LoadDouble:
|
||||||
case LoadSingle:
|
case LoadSingle:
|
||||||
case LoadPaired:
|
case LoadPaired:
|
||||||
if (thisUsed)
|
if (thisUsed)
|
||||||
regMarkUse(RI, I, getOp1(I), 1);
|
regMarkUse(RI, I, getOp1(I), 1);
|
||||||
break;
|
break;
|
||||||
|
@ -1281,7 +1319,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||||
case StoreGReg:
|
case StoreGReg:
|
||||||
case StoreLink:
|
case StoreLink:
|
||||||
case StoreCTR:
|
case StoreCTR:
|
||||||
case StoreMSR:
|
case StoreMSR:
|
||||||
case StoreGQR:
|
case StoreGQR:
|
||||||
case StoreFReg:
|
case StoreFReg:
|
||||||
if (!isImm(*getOp1(I)))
|
if (!isImm(*getOp1(I)))
|
||||||
|
@ -1415,23 +1453,23 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||||
Jit->MOV(32, R(reg), M(&MSR));
|
Jit->MOV(32, R(reg), M(&MSR));
|
||||||
RI.regs[reg] = I;
|
RI.regs[reg] = I;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LoadGQR: {
|
case LoadGQR: {
|
||||||
if (!thisUsed) break;
|
if (!thisUsed) break;
|
||||||
X64Reg reg = regFindFreeReg(RI);
|
X64Reg reg = regFindFreeReg(RI);
|
||||||
unsigned gqr = *I >> 8;
|
unsigned gqr = *I >> 8;
|
||||||
Jit->MOV(32, R(reg), M(&GQR(gqr)));
|
Jit->MOV(32, R(reg), M(&GQR(gqr)));
|
||||||
RI.regs[reg] = I;
|
RI.regs[reg] = I;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LoadCarry: {
|
case LoadCarry: {
|
||||||
if (!thisUsed) break;
|
if (!thisUsed) break;
|
||||||
X64Reg reg = regFindFreeReg(RI);
|
X64Reg reg = regFindFreeReg(RI);
|
||||||
Jit->MOV(32, R(reg), M(&PowerPC::ppcState.spr[SPR_XER]));
|
Jit->MOV(32, R(reg), M(&PowerPC::ppcState.spr[SPR_XER]));
|
||||||
Jit->SHR(32, R(reg), Imm8(29));
|
Jit->SHR(32, R(reg), Imm8(29));
|
||||||
Jit->AND(32, R(reg), Imm8(1));
|
Jit->AND(32, R(reg), Imm8(1));
|
||||||
RI.regs[reg] = I;
|
RI.regs[reg] = I;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case StoreGReg: {
|
case StoreGReg: {
|
||||||
unsigned ppcreg = *I >> 16;
|
unsigned ppcreg = *I >> 16;
|
||||||
|
@ -1462,8 +1500,8 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||||
regStoreInstToConstLoc(RI, 32, getOp1(I), &MSR);
|
regStoreInstToConstLoc(RI, 32, getOp1(I), &MSR);
|
||||||
regNormalRegClear(RI, I);
|
regNormalRegClear(RI, I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case StoreGQR: {
|
case StoreGQR: {
|
||||||
unsigned gqr = *I >> 16;
|
unsigned gqr = *I >> 16;
|
||||||
regStoreInstToConstLoc(RI, 32, getOp1(I), &GQR(gqr));
|
regStoreInstToConstLoc(RI, 32, getOp1(I), &GQR(gqr));
|
||||||
regNormalRegClear(RI, I);
|
regNormalRegClear(RI, I);
|
||||||
|
@ -1723,7 +1761,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||||
regSpill(RI, EDX);
|
regSpill(RI, EDX);
|
||||||
X64Reg reg = fregFindFreeReg(RI);
|
X64Reg reg = fregFindFreeReg(RI);
|
||||||
unsigned int quantreg = *I >> 16;
|
unsigned int quantreg = *I >> 16;
|
||||||
Jit->MOVZX(32, 16, EAX, M(((char *)&PowerPC::ppcState.spr[SPR_GQR0 + quantreg]) + 2));
|
Jit->MOVZX(32, 16, EAX, M(((char *)&GQR(quantreg)) + 2));
|
||||||
Jit->MOVZX(32, 8, EDX, R(AL));
|
Jit->MOVZX(32, 8, EDX, R(AL));
|
||||||
// FIXME: Fix ModR/M encoding to allow [EDX*4+disp32]! (MComplex can do this, no?)
|
// FIXME: Fix ModR/M encoding to allow [EDX*4+disp32]! (MComplex can do this, no?)
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
|
|
|
@ -220,6 +220,8 @@ namespace IREmitter {
|
||||||
InstLoc FoldXor(InstLoc Op1, InstLoc Op2);
|
InstLoc FoldXor(InstLoc Op1, InstLoc Op2);
|
||||||
InstLoc FoldBranchCond(InstLoc Op1, InstLoc Op2);
|
InstLoc FoldBranchCond(InstLoc Op1, InstLoc Op2);
|
||||||
InstLoc FoldICmp(unsigned Opcode, InstLoc Op1, InstLoc Op2);
|
InstLoc FoldICmp(unsigned Opcode, InstLoc Op1, InstLoc Op2);
|
||||||
|
InstLoc FoldICmpCRSigned(InstLoc Op1, InstLoc Op2);
|
||||||
|
InstLoc FoldICmpCRUnsigned(InstLoc Op1, InstLoc Op2);
|
||||||
InstLoc FoldDoubleBiOp(unsigned Opcode, InstLoc Op1, InstLoc Op2);
|
InstLoc FoldDoubleBiOp(unsigned Opcode, InstLoc Op1, InstLoc Op2);
|
||||||
|
|
||||||
InstLoc FoldInterpreterFallback(InstLoc Op1, InstLoc Op2);
|
InstLoc FoldInterpreterFallback(InstLoc Op1, InstLoc Op2);
|
||||||
|
|
Loading…
Reference in New Issue