mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 08:09:26 +01:00
Misc accumulated Jit64IL work; I don't recall whether any of these
changes individually led to perf improvements, although overall it's spending a lot less time in interpreter fallbacks. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1904 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
9cb25d6ba2
commit
ee2bf31e56
@ -38,7 +38,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include
|
||||
// ¯¯¯¯¯¯¯¯¯¯
|
||||
#ifdef JITTEST
|
||||
#if JITTEST
|
||||
#include "../Jit64IL/Jit.h"
|
||||
#else
|
||||
|
||||
|
@ -1197,11 +1197,9 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||
case RFIExit:
|
||||
case InterpreterBranch:
|
||||
case IdleLoop:
|
||||
// No liveness effects
|
||||
break;
|
||||
case ShortIdleLoop:
|
||||
case Tramp:
|
||||
if (thisUsed)
|
||||
regMarkUse(RI, I, I - 1 - (*I >> 8), 1);
|
||||
// No liveness effects
|
||||
break;
|
||||
case SExt8:
|
||||
case SExt16:
|
||||
@ -1232,6 +1230,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||
break;
|
||||
case StoreCR:
|
||||
case StoreCarry:
|
||||
case StoreFPRF:
|
||||
regMarkUse(RI, I, getOp1(I), 1);
|
||||
break;
|
||||
case StoreGReg:
|
||||
@ -1277,6 +1276,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||
case FPMerge01:
|
||||
case FPMerge10:
|
||||
case FPMerge11:
|
||||
case FDCmpCR:
|
||||
case InsertDoubleInMReg:
|
||||
if (thisUsed) {
|
||||
regMarkUse(RI, I, getOp1(I), 1);
|
||||
@ -1411,6 +1411,15 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||
regNormalRegClear(RI, I);
|
||||
break;
|
||||
}
|
||||
case StoreFPRF: {
|
||||
Jit->MOV(32, R(ECX), regLocForInst(RI, getOp1(I)));
|
||||
Jit->AND(32, R(ECX), Imm8(0x1F));
|
||||
Jit->SHL(32, R(ECX), Imm8(12));
|
||||
Jit->AND(32, M(&FPSCR), Imm32(~(0x1F << 12)));
|
||||
Jit->OR(32, M(&FPSCR), R(ECX));
|
||||
regNormalRegClear(RI, I);
|
||||
break;
|
||||
}
|
||||
case Load8: {
|
||||
regEmitMemLoad(RI, I, 8);
|
||||
break;
|
||||
@ -1851,6 +1860,35 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||
fregEmitBinInst(RI, I, &Jit64::SUBSD);
|
||||
break;
|
||||
}
|
||||
case FDCmpCR: {
|
||||
X64Reg destreg = regFindFreeReg(RI);
|
||||
// TODO: Add case for NaN (CC_P)
|
||||
Jit->MOVSD(XMM0, fregLocForInst(RI, getOp1(I)));
|
||||
Jit->UCOMISD(XMM0, fregLocForInst(RI, getOp2(I)));
|
||||
FixupBranch pNan = Jit->J_CC(CC_P);
|
||||
FixupBranch pEqual = Jit->J_CC(CC_Z);
|
||||
FixupBranch pLesser = Jit->J_CC(CC_C);
|
||||
// Greater
|
||||
Jit->MOV(32, R(destreg), Imm32(0x4));
|
||||
FixupBranch continue1 = Jit->J();
|
||||
// NaN
|
||||
Jit->SetJumpTarget(pNan);
|
||||
Jit->MOV(32, R(destreg), Imm32(0x1));
|
||||
FixupBranch continue2 = Jit->J();
|
||||
// Equal
|
||||
Jit->SetJumpTarget(pEqual);
|
||||
Jit->MOV(32, R(destreg), Imm32(0x2));
|
||||
FixupBranch continue3 = Jit->J();
|
||||
// Less
|
||||
Jit->SetJumpTarget(pLesser);
|
||||
Jit->MOV(32, R(destreg), Imm32(0x8));
|
||||
Jit->SetJumpTarget(continue1);
|
||||
Jit->SetJumpTarget(continue2);
|
||||
Jit->SetJumpTarget(continue3);
|
||||
RI.regs[destreg] = I;
|
||||
fregNormalRegClear(RI, I);
|
||||
break;
|
||||
}
|
||||
case FPAdd: {
|
||||
if (!thisUsed) break;
|
||||
fregEmitBinInst(RI, I, &Jit64::ADDPS);
|
||||
@ -1962,7 +2000,14 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||
unsigned IdleParam = ibuild->GetImmValue(getOp1(I));
|
||||
unsigned InstLoc = ibuild->GetImmValue(getOp2(I));
|
||||
Jit->ABI_CallFunctionC((void *)&PowerPC::OnIdle, IdleParam);
|
||||
Jit->MOV(32, M(&PowerPC::ppcState.pc), Imm32(InstLoc + 12));
|
||||
Jit->MOV(32, M(&PC), Imm32(InstLoc + 12));
|
||||
Jit->JMP(asm_routines.testExceptions, true);
|
||||
break;
|
||||
}
|
||||
case ShortIdleLoop: {
|
||||
unsigned InstLoc = ibuild->GetImmValue(getOp1(I));
|
||||
Jit->ABI_CallFunction((void *)&CoreTiming::Idle);
|
||||
Jit->MOV(32, M(&PC), Imm32(InstLoc));
|
||||
Jit->JMP(asm_routines.testExceptions, true);
|
||||
break;
|
||||
}
|
||||
@ -1998,25 +2043,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||
Jit->WriteRfiExitDestInEAX();
|
||||
break;
|
||||
}
|
||||
case Tramp: {
|
||||
if (!thisUsed) break;
|
||||
// FIXME: Optimize!
|
||||
InstLoc Op = I - 1 - (*I >> 8);
|
||||
if (isFResult(*Op)) {
|
||||
X64Reg reg = fregFindFreeReg(RI);
|
||||
Jit->MOVAPD(reg, fregLocForInst(RI, Op));
|
||||
RI.fregs[reg] = I;
|
||||
if (RI.IInfo[I - RI.FirstI] & 4)
|
||||
fregClearInst(RI, Op);
|
||||
} else {
|
||||
X64Reg reg = regFindFreeReg(RI);
|
||||
Jit->MOV(32, R(reg), regLocForInst(RI, Op));
|
||||
RI.regs[reg] = I;
|
||||
if (RI.IInfo[I - RI.FirstI] & 4)
|
||||
regClearInst(RI, Op);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Tramp: break;
|
||||
case Nop: break;
|
||||
default:
|
||||
PanicAlert("Unknown JIT instruction; aborting!");
|
||||
@ -2034,7 +2061,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||
}
|
||||
}
|
||||
|
||||
if (UseProfile && RI.numSpills)
|
||||
if (!RI.MakeProfile && RI.numSpills)
|
||||
printf("Block: %x, numspills %d\n", Jit->js.blockStart, RI.numSpills);
|
||||
|
||||
Jit->UD2();
|
||||
|
@ -54,6 +54,7 @@ namespace IREmitter {
|
||||
StoreCarry,
|
||||
StoreCTR,
|
||||
StoreMSR,
|
||||
StoreFPRF,
|
||||
// Arbitrary interpreter instruction
|
||||
InterpreterFallback,
|
||||
|
||||
@ -184,6 +185,7 @@ namespace IREmitter {
|
||||
StoreSingle,
|
||||
StoreDouble,
|
||||
StoreFReg,
|
||||
FDCmpCR,
|
||||
|
||||
// "Trinary" operators
|
||||
// FIXME: Need to change representation!
|
||||
@ -197,7 +199,9 @@ namespace IREmitter {
|
||||
SystemCall,
|
||||
RFIExit,
|
||||
InterpreterBranch,
|
||||
IdleLoop,
|
||||
IdleLoop, // The "usual" idle loop, load+compare+branch
|
||||
ShortIdleLoop, // Idle loop seen in homebrew like wii mahjong,
|
||||
// just a branch
|
||||
|
||||
// "Opcode" representing a register too far away to
|
||||
// reference directly; this is a size optimization
|
||||
@ -227,11 +231,19 @@ namespace IREmitter {
|
||||
}
|
||||
|
||||
InstLoc inline getOp1(InstLoc i) {
|
||||
return i - 1 - ((*i >> 8) & 255);
|
||||
i = i - 1 - ((*i >> 8) & 255);
|
||||
if (getOpcode(*i) == Tramp) {
|
||||
i = i - 1 - (*i >> 8);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
InstLoc inline getOp2(InstLoc i) {
|
||||
return i - 1 - ((*i >> 16) & 255);
|
||||
i = i - 1 - ((*i >> 16) & 255);
|
||||
if (getOpcode(*i) == Tramp) {
|
||||
i = i - 1 - (*i >> 8);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
class IRBuilder {
|
||||
@ -288,6 +300,9 @@ namespace IREmitter {
|
||||
InstLoc EmitStoreMSR(InstLoc val) {
|
||||
return FoldUOp(StoreMSR, val);
|
||||
}
|
||||
InstLoc EmitStoreFPRF(InstLoc value) {
|
||||
return FoldUOp(StoreFPRF, value);
|
||||
}
|
||||
InstLoc EmitLoadGReg(unsigned reg) {
|
||||
return FoldZeroOp(LoadGReg, reg);
|
||||
}
|
||||
@ -390,6 +405,9 @@ namespace IREmitter {
|
||||
InstLoc EmitInterpreterBranch() {
|
||||
return FoldZeroOp(InterpreterBranch, 0);
|
||||
}
|
||||
InstLoc EmitLoadCarry() {
|
||||
return FoldZeroOp(LoadCarry, 0);
|
||||
}
|
||||
InstLoc EmitStoreCarry(InstLoc op1) {
|
||||
return FoldUOp(StoreCarry, op1);
|
||||
}
|
||||
@ -402,6 +420,9 @@ namespace IREmitter {
|
||||
InstLoc EmitIdleLoop(InstLoc idleParam, InstLoc pc) {
|
||||
return FoldBiOp(IdleLoop, idleParam, pc);
|
||||
}
|
||||
InstLoc EmitShortIdleLoop(InstLoc pc) {
|
||||
return FoldUOp(ShortIdleLoop, pc);
|
||||
}
|
||||
InstLoc EmitLoadSingle(InstLoc addr) {
|
||||
return FoldUOp(LoadSingle, addr);
|
||||
}
|
||||
@ -498,6 +519,9 @@ namespace IREmitter {
|
||||
InstLoc EmitDoubleToSingle(InstLoc op1) {
|
||||
return FoldUOp(DoubleToSingle, op1);
|
||||
}
|
||||
InstLoc EmitFDCmpCR(InstLoc op1, InstLoc op2) {
|
||||
return FoldBiOp(FDCmpCR, op1, op2);
|
||||
}
|
||||
|
||||
void StartBackPass() { curReadPtr = &InstList[InstList.size()]; }
|
||||
void StartForwardPass() { curReadPtr = &InstList[0]; }
|
||||
|
@ -280,12 +280,9 @@ public:
|
||||
void subfx(UGeckoInstruction inst);
|
||||
void subfex(UGeckoInstruction inst);
|
||||
|
||||
void lbzx(UGeckoInstruction inst);
|
||||
void lwzx(UGeckoInstruction inst);
|
||||
void lXzx(UGeckoInstruction inst);
|
||||
void lhax(UGeckoInstruction inst);
|
||||
|
||||
void lwzux(UGeckoInstruction inst);
|
||||
|
||||
void stXx(UGeckoInstruction inst);
|
||||
|
||||
void lmw(UGeckoInstruction inst);
|
||||
|
@ -68,6 +68,11 @@ using namespace Gen;
|
||||
else
|
||||
destination = js.compilerPC + SignExt26(inst.LI << 2);
|
||||
|
||||
if (destination == js.compilerPC) {
|
||||
ibuild.EmitShortIdleLoop(ibuild.EmitIntConst(js.compilerPC));
|
||||
return;
|
||||
}
|
||||
|
||||
ibuild.EmitBranchUncond(ibuild.EmitIntConst(destination));
|
||||
}
|
||||
|
||||
@ -109,7 +114,8 @@ using namespace Gen;
|
||||
}
|
||||
|
||||
if (!Test) {
|
||||
PanicAlert("Unconditional conditional branch?!");
|
||||
Test = ibuild.EmitIntConst(1);
|
||||
//PanicAlert("Unconditional conditional branch?!");
|
||||
}
|
||||
|
||||
u32 destination;
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
void Jit64::fp_arith_s(UGeckoInstruction inst)
|
||||
{
|
||||
if (inst.Rc || inst.OPCD != 59 || (inst.SUBOP5 != 25 && inst.SUBOP5 != 20 && inst.SUBOP5 != 21)) {
|
||||
if (inst.Rc || (inst.SUBOP5 != 25 && inst.SUBOP5 != 20 && inst.SUBOP5 != 21)) {
|
||||
Default(inst); return;
|
||||
}
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA);
|
||||
@ -61,22 +61,24 @@
|
||||
|
||||
void Jit64::fmaddXX(UGeckoInstruction inst)
|
||||
{
|
||||
if (inst.Rc || inst.OPCD != 59) {
|
||||
if (inst.Rc) {
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
bool single_precision = inst.OPCD == 59;
|
||||
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA);
|
||||
val = ibuild.EmitDoubleToSingle(val);
|
||||
val = ibuild.EmitFSMul(val, ibuild.EmitDoubleToSingle(ibuild.EmitLoadFReg(inst.FC)));
|
||||
val = ibuild.EmitFDMul(val, ibuild.EmitLoadFReg(inst.FC));
|
||||
if (inst.SUBOP5 & 1)
|
||||
val = ibuild.EmitFSAdd(val, ibuild.EmitDoubleToSingle(ibuild.EmitLoadFReg(inst.FB)));
|
||||
val = ibuild.EmitFDAdd(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
else
|
||||
val = ibuild.EmitFSSub(val, ibuild.EmitDoubleToSingle(ibuild.EmitLoadFReg(inst.FB)));
|
||||
val = ibuild.EmitFDSub(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
if (inst.SUBOP5 & 2)
|
||||
val = ibuild.EmitFSNeg(val);
|
||||
val = ibuild.EmitFDNeg(val);
|
||||
if (inst.OPCD == 59) {
|
||||
val = ibuild.EmitDoubleToSingle(val);
|
||||
val = ibuild.EmitDupSingleToMReg(val);
|
||||
} else {
|
||||
val = ibuild.EmitInsertDoubleInMReg(val, ibuild.EmitLoadFReg(inst.FD));
|
||||
}
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
}
|
||||
|
||||
@ -92,6 +94,11 @@
|
||||
|
||||
void Jit64::fcmpx(UGeckoInstruction inst)
|
||||
{
|
||||
Default(inst);
|
||||
return;
|
||||
printf("fcmpx at %x\n", js.compilerPC);
|
||||
IREmitter::InstLoc lhs, rhs, res;
|
||||
lhs = ibuild.EmitLoadFReg(inst.FA);
|
||||
rhs = ibuild.EmitLoadFReg(inst.FB);
|
||||
res = ibuild.EmitFDCmpCR(lhs, rhs);
|
||||
ibuild.EmitStoreFPRF(res);
|
||||
ibuild.EmitStoreCR(res, inst.CRFD);
|
||||
}
|
||||
|
@ -211,19 +211,21 @@
|
||||
|
||||
void Jit64::subfex(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START;
|
||||
Default(inst);
|
||||
return;
|
||||
/*
|
||||
u32 a = m_GPR[_inst.RA];
|
||||
u32 b = m_GPR[_inst.RB];
|
||||
int carry = GetCarry();
|
||||
m_GPR[_inst.RD] = (~a) + b + carry;
|
||||
SetCarry(Helper_Carry(~a, b) || Helper_Carry((~a) + b, carry));
|
||||
|
||||
if (_inst.OE) PanicAlert("OE: subfcx");
|
||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||
*/
|
||||
if (inst.OE) PanicAlert("OE: subfex");
|
||||
IREmitter::InstLoc val, test, lhs, rhs, carry;
|
||||
rhs = ibuild.EmitLoadGReg(inst.RA);
|
||||
carry = ibuild.EmitLoadCarry();
|
||||
rhs = ibuild.EmitXor(rhs, ibuild.EmitIntConst(-1));
|
||||
rhs = ibuild.EmitAdd(rhs, carry);
|
||||
test = ibuild.EmitICmpEq(rhs, ibuild.EmitIntConst(0));
|
||||
test = ibuild.EmitAnd(test, carry);
|
||||
lhs = ibuild.EmitLoadGReg(inst.RB);
|
||||
val = ibuild.EmitAdd(lhs, rhs);
|
||||
ibuild.EmitStoreGReg(val, inst.RD);
|
||||
test = ibuild.EmitOr(test, ibuild.EmitICmpUgt(lhs, val));
|
||||
ibuild.EmitStoreCarry(test);
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
||||
void Jit64::subfx(UGeckoInstruction inst)
|
||||
|
@ -39,24 +39,6 @@
|
||||
//#define INSTRUCTION_START Default(inst); return;
|
||||
#define INSTRUCTION_START
|
||||
|
||||
void Jit64::lbzx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB);
|
||||
if (inst.RA)
|
||||
addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA));
|
||||
ibuild.EmitStoreGReg(ibuild.EmitLoad8(addr), inst.RD);
|
||||
}
|
||||
|
||||
void Jit64::lwzx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB);
|
||||
if (inst.RA)
|
||||
addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA));
|
||||
ibuild.EmitStoreGReg(ibuild.EmitLoad32(addr), inst.RD);
|
||||
}
|
||||
|
||||
void Jit64::lhax(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
@ -113,15 +95,24 @@ void Jit64::lha(UGeckoInstruction inst)
|
||||
ibuild.EmitStoreGReg(val, inst.RD);
|
||||
}
|
||||
|
||||
void Jit64::lwzux(UGeckoInstruction inst)
|
||||
void Jit64::lXzx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB);
|
||||
if (inst.RA) {
|
||||
addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA));
|
||||
if (inst.SUBOP10 & 32)
|
||||
ibuild.EmitStoreGReg(addr, inst.RA);
|
||||
}
|
||||
ibuild.EmitStoreGReg(ibuild.EmitLoad32(addr), inst.RD);
|
||||
IREmitter::InstLoc val;
|
||||
switch (inst.SUBOP10 & ~32)
|
||||
{
|
||||
default: PanicAlert("lXzx: invalid access size");
|
||||
case 23: val = ibuild.EmitLoad32(addr); break; //lwzx
|
||||
case 279: val = ibuild.EmitLoad16(addr); break; //lhzx
|
||||
case 87: val = ibuild.EmitLoad8(addr); break; //lbzx
|
||||
}
|
||||
ibuild.EmitStoreGReg(val, inst.RD);
|
||||
}
|
||||
|
||||
// Zero cache line.
|
||||
@ -183,10 +174,28 @@ void Jit64::stXx(UGeckoInstruction inst)
|
||||
// A few games use these heavily in video codecs.
|
||||
void Jit64::lmw(UGeckoInstruction inst)
|
||||
{
|
||||
Default(inst); return;
|
||||
INSTRUCTION_START
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16);
|
||||
if (inst.RA)
|
||||
addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA));
|
||||
for (int i = inst.RD; i < 32; i++)
|
||||
{
|
||||
IREmitter::InstLoc val = ibuild.EmitLoad32(addr);
|
||||
ibuild.EmitStoreGReg(val, i);
|
||||
addr = ibuild.EmitAdd(addr, ibuild.EmitIntConst(4));
|
||||
}
|
||||
}
|
||||
|
||||
void Jit64::stmw(UGeckoInstruction inst)
|
||||
{
|
||||
Default(inst); return;
|
||||
INSTRUCTION_START
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16);
|
||||
if (inst.RA)
|
||||
addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA));
|
||||
for (int i = inst.RD; i < 32; i++)
|
||||
{
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadGReg(i);
|
||||
ibuild.EmitStore32(val, addr);
|
||||
addr = ibuild.EmitAdd(addr, ibuild.EmitIntConst(4));
|
||||
}
|
||||
}
|
||||
|
@ -167,12 +167,21 @@ static GekkoOPTemplate primarytable[] =
|
||||
{28, Interpreter::andi_rc, &Jit64::reg_imm, {"andi_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}},
|
||||
{29, Interpreter::andis_rc, &Jit64::reg_imm, {"andis_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}},
|
||||
|
||||
#if JITTEST
|
||||
{32, Interpreter::lwz, &Jit64::lXz, {"lwz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}},
|
||||
{33, Interpreter::lwzu, &Jit64::lXz, {"lwzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}},
|
||||
{34, Interpreter::lbz, &Jit64::lXz, {"lbz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}},
|
||||
{35, Interpreter::lbzu, &Jit64::lXz, {"lbzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}},
|
||||
{40, Interpreter::lhz, &Jit64::lXz, {"lhz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}},
|
||||
{41, Interpreter::lhzu, &Jit64::lXz, {"lhzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}},
|
||||
#else
|
||||
{32, Interpreter::lwz, &Jit64::lXz, {"lwz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}},
|
||||
{33, Interpreter::lwzu, &Jit64::Default, {"lwzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}},
|
||||
{34, Interpreter::lbz, &Jit64::lXz, {"lbz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}},
|
||||
{35, Interpreter::lbzu, &Jit64::Default, {"lbzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}},
|
||||
{40, Interpreter::lhz, &Jit64::lXz, {"lhz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}},
|
||||
{41, Interpreter::lhzu, &Jit64::Default, {"lhzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}},
|
||||
#endif
|
||||
{42, Interpreter::lha, &Jit64::lha, {"lha", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}},
|
||||
{43, Interpreter::lhau, &Jit64::Default, {"lhau", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}},
|
||||
|
||||
@ -302,13 +311,33 @@ static GekkoOPTemplate table31[] =
|
||||
{24, Interpreter::slwx, &Jit64::slwx, {"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
||||
|
||||
{54, Interpreter::dcbst, &Jit64::Default, {"dcbst", OPTYPE_DCACHE, 0, 4}},
|
||||
#if JITTEST
|
||||
{86, Interpreter::dcbf, &Jit64::DoNothing, {"dcbf", OPTYPE_DCACHE, 0, 4}},
|
||||
#else
|
||||
{86, Interpreter::dcbf, &Jit64::Default, {"dcbf", OPTYPE_DCACHE, 0, 4}},
|
||||
#endif
|
||||
{246, Interpreter::dcbtst, &Jit64::Default, {"dcbtst", OPTYPE_DCACHE, 0, 1}},
|
||||
{278, Interpreter::dcbt, &Jit64::Default, {"dcbt", OPTYPE_DCACHE, 0, 1}},
|
||||
{470, Interpreter::dcbi, &Jit64::Default, {"dcbi", OPTYPE_DCACHE, 0, 4}},
|
||||
{758, Interpreter::dcba, &Jit64::Default, {"dcba", OPTYPE_DCACHE, 0, 4}},
|
||||
{1014, Interpreter::dcbz, &Jit64::dcbz, {"dcbz", OPTYPE_DCACHE, 0, 4}},
|
||||
#if JITTEST
|
||||
//load word
|
||||
{23, Interpreter::lwzx, &Jit64::lXzx, {"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
|
||||
{55, Interpreter::lwzux, &Jit64::lXzx, {"lwzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}},
|
||||
|
||||
//load halfword
|
||||
{279, Interpreter::lhzx, &Jit64::lXzx, {"lhzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
|
||||
{311, Interpreter::lhzux, &Jit64::lXzx, {"lhzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}},
|
||||
|
||||
//load halfword signextend
|
||||
{343, Interpreter::lhax, &Jit64::lhax, {"lhax", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
|
||||
{375, Interpreter::lhaux, &Jit64::Default, {"lhaux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}},
|
||||
|
||||
//load byte
|
||||
{87, Interpreter::lbzx, &Jit64::lXzx, {"lbzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
|
||||
{119, Interpreter::lbzux, &Jit64::lXzx, {"lbzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}},
|
||||
#else
|
||||
//load word
|
||||
{23, Interpreter::lwzx, &Jit64::lwzx, {"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
|
||||
{55, Interpreter::lwzux, &Jit64::lwzux, {"lwzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}},
|
||||
@ -324,7 +353,7 @@ static GekkoOPTemplate table31[] =
|
||||
//load byte
|
||||
{87, Interpreter::lbzx, &Jit64::lbzx, {"lbzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
|
||||
{119, Interpreter::lbzux, &Jit64::Default, {"lbzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}},
|
||||
|
||||
#endif
|
||||
//load byte reverse
|
||||
{534, Interpreter::lwbrx, &Jit64::Default, {"lwbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
|
||||
{790, Interpreter::lhbrx, &Jit64::Default, {"lhbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
|
||||
|
Loading…
x
Reference in New Issue
Block a user