mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
JITIL: Disable all load/store instructions in 64-bit mode. This actually makes a lot of games work - but slowly. Investigation needed. Reindent a bunch of code.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3405 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -71,6 +71,14 @@ struct CONTEXT
|
||||
Core::g_CoreStartupParameter.bJIT##type##Off) \
|
||||
{Default(inst); return;}
|
||||
|
||||
#ifdef _M_X64
|
||||
#define DISABLE64 \
|
||||
{Default(inst); return;}
|
||||
#else
|
||||
#define DISABLE64
|
||||
#endif
|
||||
|
||||
|
||||
class TrampolineCache : public Gen::XCodeBlock
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -45,150 +45,149 @@
|
||||
|
||||
using namespace Gen;
|
||||
|
||||
void Jit64::sc(UGeckoInstruction inst)
|
||||
{
|
||||
ibuild.EmitSystemCall(ibuild.EmitIntConst(js.compilerPC));
|
||||
void Jit64::sc(UGeckoInstruction inst)
|
||||
{
|
||||
ibuild.EmitSystemCall(ibuild.EmitIntConst(js.compilerPC));
|
||||
}
|
||||
|
||||
void Jit64::rfi(UGeckoInstruction inst)
|
||||
{
|
||||
ibuild.EmitRFIExit();
|
||||
}
|
||||
|
||||
void Jit64::bx(UGeckoInstruction inst)
|
||||
{
|
||||
NORMALBRANCH_START
|
||||
INSTRUCTION_START;
|
||||
|
||||
if (inst.LK)
|
||||
ibuild.EmitStoreLink(ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
|
||||
u32 destination;
|
||||
if (inst.AA)
|
||||
destination = SignExt26(inst.LI << 2);
|
||||
else
|
||||
destination = js.compilerPC + SignExt26(inst.LI << 2);
|
||||
|
||||
if (destination == js.compilerPC) {
|
||||
ibuild.EmitShortIdleLoop(ibuild.EmitIntConst(js.compilerPC));
|
||||
return;
|
||||
}
|
||||
|
||||
void Jit64::rfi(UGeckoInstruction inst)
|
||||
ibuild.EmitBranchUncond(ibuild.EmitIntConst(destination));
|
||||
}
|
||||
|
||||
static IREmitter::InstLoc TestBranch(IREmitter::IRBuilder& ibuild, UGeckoInstruction inst) {
|
||||
IREmitter::InstLoc CRTest = 0, CTRTest = 0;
|
||||
if ((inst.BO & 16) == 0) // Test a CR bit
|
||||
{
|
||||
ibuild.EmitRFIExit();
|
||||
IREmitter::InstLoc CRReg = ibuild.EmitLoadCR(inst.BI >> 2);
|
||||
IREmitter::InstLoc CRCmp = ibuild.EmitIntConst(8 >> (inst.BI & 3));
|
||||
CRTest = ibuild.EmitAnd(CRReg, CRCmp);
|
||||
if (!(inst.BO & 8))
|
||||
CRTest = ibuild.EmitXor(CRTest, CRCmp);
|
||||
}
|
||||
|
||||
void Jit64::bx(UGeckoInstruction inst)
|
||||
{
|
||||
NORMALBRANCH_START
|
||||
INSTRUCTION_START;
|
||||
|
||||
if (inst.LK)
|
||||
ibuild.EmitStoreLink(ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
|
||||
u32 destination;
|
||||
if (inst.AA)
|
||||
destination = SignExt26(inst.LI << 2);
|
||||
else
|
||||
destination = js.compilerPC + SignExt26(inst.LI << 2);
|
||||
|
||||
if (destination == js.compilerPC) {
|
||||
ibuild.EmitShortIdleLoop(ibuild.EmitIntConst(js.compilerPC));
|
||||
return;
|
||||
}
|
||||
|
||||
ibuild.EmitBranchUncond(ibuild.EmitIntConst(destination));
|
||||
}
|
||||
|
||||
static IREmitter::InstLoc TestBranch(IREmitter::IRBuilder& ibuild, UGeckoInstruction inst) {
|
||||
IREmitter::InstLoc CRTest = 0, CTRTest = 0;
|
||||
if ((inst.BO & 16) == 0) // Test a CR bit
|
||||
{
|
||||
IREmitter::InstLoc CRReg = ibuild.EmitLoadCR(inst.BI >> 2);
|
||||
IREmitter::InstLoc CRCmp = ibuild.EmitIntConst(8 >> (inst.BI & 3));
|
||||
CRTest = ibuild.EmitAnd(CRReg, CRCmp);
|
||||
if (!(inst.BO & 8))
|
||||
CRTest = ibuild.EmitXor(CRTest, CRCmp);
|
||||
}
|
||||
|
||||
if ((inst.BO & 4) == 0) {
|
||||
IREmitter::InstLoc c = ibuild.EmitLoadCTR();
|
||||
c = ibuild.EmitSub(c, ibuild.EmitIntConst(1));
|
||||
ibuild.EmitStoreCTR(c);
|
||||
if (inst.BO & 2) {
|
||||
CTRTest = ibuild.EmitICmpEq(c,
|
||||
ibuild.EmitIntConst(0));
|
||||
} else {
|
||||
CTRTest = c;
|
||||
}
|
||||
}
|
||||
|
||||
IREmitter::InstLoc Test = CRTest;
|
||||
if (CTRTest) {
|
||||
if (Test)
|
||||
Test = ibuild.EmitAnd(Test, CTRTest);
|
||||
else
|
||||
Test = CTRTest;
|
||||
}
|
||||
|
||||
if (!Test) {
|
||||
Test = ibuild.EmitIntConst(1);
|
||||
}
|
||||
return Test;
|
||||
}
|
||||
|
||||
void Jit64::bcx(UGeckoInstruction inst)
|
||||
{
|
||||
NORMALBRANCH_START
|
||||
if (inst.LK)
|
||||
ibuild.EmitStoreLink(
|
||||
ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
|
||||
IREmitter::InstLoc Test = TestBranch(ibuild, inst);
|
||||
|
||||
u32 destination;
|
||||
if(inst.AA)
|
||||
destination = SignExt16(inst.BD << 2);
|
||||
else
|
||||
destination = js.compilerPC + SignExt16(inst.BD << 2);
|
||||
|
||||
if (Core::GetStartupParameter().bSkipIdle &&
|
||||
inst.hex == 0x4182fff8 &&
|
||||
(Memory::ReadUnchecked_U32(js.compilerPC - 8) & 0xFFFF0000) == 0x800D0000 &&
|
||||
(Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x28000000 ||
|
||||
(Core::GetStartupParameter().bWii && Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x2C000000))
|
||||
)
|
||||
{
|
||||
ibuild.EmitIdleBranch(Test, ibuild.EmitIntConst(destination));
|
||||
}
|
||||
else
|
||||
{
|
||||
ibuild.EmitBranchCond(Test, ibuild.EmitIntConst(destination));
|
||||
}
|
||||
ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
}
|
||||
|
||||
void Jit64::bcctrx(UGeckoInstruction inst)
|
||||
{
|
||||
NORMALBRANCH_START
|
||||
if ((inst.BO & 4) == 0) {
|
||||
IREmitter::InstLoc c = ibuild.EmitLoadCTR();
|
||||
c = ibuild.EmitSub(c, ibuild.EmitIntConst(1));
|
||||
ibuild.EmitStoreCTR(c);
|
||||
}
|
||||
IREmitter::InstLoc test;
|
||||
if ((inst.BO & 16) == 0) // Test a CR bit
|
||||
{
|
||||
IREmitter::InstLoc CRReg = ibuild.EmitLoadCR(inst.BI >> 2);
|
||||
IREmitter::InstLoc CRCmp = ibuild.EmitIntConst(8 >> (inst.BI & 3));
|
||||
test = ibuild.EmitAnd(CRReg, CRCmp);
|
||||
if (!(inst.BO & 8))
|
||||
test = ibuild.EmitXor(test, CRCmp);
|
||||
if ((inst.BO & 4) == 0) {
|
||||
IREmitter::InstLoc c = ibuild.EmitLoadCTR();
|
||||
c = ibuild.EmitSub(c, ibuild.EmitIntConst(1));
|
||||
ibuild.EmitStoreCTR(c);
|
||||
if (inst.BO & 2) {
|
||||
CTRTest = ibuild.EmitICmpEq(c,
|
||||
ibuild.EmitIntConst(0));
|
||||
} else {
|
||||
test = ibuild.EmitIntConst(1);
|
||||
CTRTest = c;
|
||||
}
|
||||
test = ibuild.EmitICmpEq(test, ibuild.EmitIntConst(0));
|
||||
ibuild.EmitBranchCond(test, ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
|
||||
IREmitter::InstLoc destination = ibuild.EmitLoadCTR();
|
||||
destination = ibuild.EmitAnd(destination, ibuild.EmitIntConst(-4));
|
||||
if (inst.LK)
|
||||
ibuild.EmitStoreLink(ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
ibuild.EmitBranchUncond(destination);
|
||||
}
|
||||
|
||||
void Jit64::bclrx(UGeckoInstruction inst)
|
||||
IREmitter::InstLoc Test = CRTest;
|
||||
if (CTRTest) {
|
||||
if (Test)
|
||||
Test = ibuild.EmitAnd(Test, CTRTest);
|
||||
else
|
||||
Test = CTRTest;
|
||||
}
|
||||
|
||||
if (!Test) {
|
||||
Test = ibuild.EmitIntConst(1);
|
||||
}
|
||||
return Test;
|
||||
}
|
||||
|
||||
void Jit64::bcx(UGeckoInstruction inst)
|
||||
{
|
||||
NORMALBRANCH_START
|
||||
if (inst.LK)
|
||||
ibuild.EmitStoreLink(
|
||||
ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
|
||||
IREmitter::InstLoc Test = TestBranch(ibuild, inst);
|
||||
|
||||
u32 destination;
|
||||
if(inst.AA)
|
||||
destination = SignExt16(inst.BD << 2);
|
||||
else
|
||||
destination = js.compilerPC + SignExt16(inst.BD << 2);
|
||||
|
||||
if (Core::GetStartupParameter().bSkipIdle &&
|
||||
inst.hex == 0x4182fff8 &&
|
||||
(Memory::ReadUnchecked_U32(js.compilerPC - 8) & 0xFFFF0000) == 0x800D0000 &&
|
||||
(Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x28000000 ||
|
||||
(Core::GetStartupParameter().bWii && Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x2C000000))
|
||||
)
|
||||
{
|
||||
ibuild.EmitIdleBranch(Test, ibuild.EmitIntConst(destination));
|
||||
}
|
||||
else
|
||||
{
|
||||
NORMALBRANCH_START
|
||||
if (inst.hex == 0x4e800020) {
|
||||
ibuild.EmitBranchUncond(ibuild.EmitLoadLink());
|
||||
return;
|
||||
}
|
||||
IREmitter::InstLoc test = TestBranch(ibuild, inst);
|
||||
test = ibuild.EmitICmpEq(test, ibuild.EmitIntConst(0));
|
||||
ibuild.EmitBranchCond(test, ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
|
||||
IREmitter::InstLoc destination = ibuild.EmitLoadLink();
|
||||
destination = ibuild.EmitAnd(destination, ibuild.EmitIntConst(-4));
|
||||
if (inst.LK)
|
||||
ibuild.EmitStoreLink(ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
ibuild.EmitBranchUncond(destination);
|
||||
ibuild.EmitBranchCond(Test, ibuild.EmitIntConst(destination));
|
||||
}
|
||||
ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
}
|
||||
|
||||
void Jit64::bcctrx(UGeckoInstruction inst)
|
||||
{
|
||||
NORMALBRANCH_START
|
||||
if ((inst.BO & 4) == 0) {
|
||||
IREmitter::InstLoc c = ibuild.EmitLoadCTR();
|
||||
c = ibuild.EmitSub(c, ibuild.EmitIntConst(1));
|
||||
ibuild.EmitStoreCTR(c);
|
||||
}
|
||||
IREmitter::InstLoc test;
|
||||
if ((inst.BO & 16) == 0) // Test a CR bit
|
||||
{
|
||||
IREmitter::InstLoc CRReg = ibuild.EmitLoadCR(inst.BI >> 2);
|
||||
IREmitter::InstLoc CRCmp = ibuild.EmitIntConst(8 >> (inst.BI & 3));
|
||||
test = ibuild.EmitAnd(CRReg, CRCmp);
|
||||
if (!(inst.BO & 8))
|
||||
test = ibuild.EmitXor(test, CRCmp);
|
||||
} else {
|
||||
test = ibuild.EmitIntConst(1);
|
||||
}
|
||||
test = ibuild.EmitICmpEq(test, ibuild.EmitIntConst(0));
|
||||
ibuild.EmitBranchCond(test, ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
|
||||
IREmitter::InstLoc destination = ibuild.EmitLoadCTR();
|
||||
destination = ibuild.EmitAnd(destination, ibuild.EmitIntConst(-4));
|
||||
if (inst.LK)
|
||||
ibuild.EmitStoreLink(ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
ibuild.EmitBranchUncond(destination);
|
||||
}
|
||||
|
||||
void Jit64::bclrx(UGeckoInstruction inst)
|
||||
{
|
||||
NORMALBRANCH_START
|
||||
if (inst.hex == 0x4e800020) {
|
||||
ibuild.EmitBranchUncond(ibuild.EmitLoadLink());
|
||||
return;
|
||||
}
|
||||
IREmitter::InstLoc test = TestBranch(ibuild, inst);
|
||||
test = ibuild.EmitICmpEq(test, ibuild.EmitIntConst(0));
|
||||
ibuild.EmitBranchCond(test, ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
|
||||
IREmitter::InstLoc destination = ibuild.EmitLoadLink();
|
||||
destination = ibuild.EmitAnd(destination, ibuild.EmitIntConst(-4));
|
||||
if (inst.LK)
|
||||
ibuild.EmitStoreLink(ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
ibuild.EmitBranchUncond(destination);
|
||||
}
|
||||
|
||||
@@ -28,86 +28,86 @@
|
||||
//#define INSTRUCTION_START Default(inst); return;
|
||||
#define INSTRUCTION_START
|
||||
|
||||
void Jit64::fp_arith_s(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(FloatingPoint)
|
||||
if (inst.Rc || (inst.SUBOP5 != 25 && inst.SUBOP5 != 20 && inst.SUBOP5 != 21)) {
|
||||
Default(inst); return;
|
||||
}
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA);
|
||||
switch (inst.SUBOP5)
|
||||
{
|
||||
case 25: //mul
|
||||
val = ibuild.EmitFDMul(val, ibuild.EmitLoadFReg(inst.FC));
|
||||
break;
|
||||
case 18: //div
|
||||
case 20: //sub
|
||||
val = ibuild.EmitFDSub(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
break;
|
||||
case 21: //add
|
||||
val = ibuild.EmitFDAdd(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
break;
|
||||
case 23: //sel
|
||||
case 24: //res
|
||||
default:
|
||||
_assert_msg_(DYNA_REC, 0, "fp_arith_s WTF!!!");
|
||||
}
|
||||
|
||||
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);
|
||||
void Jit64::fp_arith_s(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(FloatingPoint)
|
||||
if (inst.Rc || (inst.SUBOP5 != 25 && inst.SUBOP5 != 20 && inst.SUBOP5 != 21)) {
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
void Jit64::fmaddXX(UGeckoInstruction inst)
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA);
|
||||
switch (inst.SUBOP5)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(FloatingPoint)
|
||||
if (inst.Rc) {
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA);
|
||||
case 25: //mul
|
||||
val = ibuild.EmitFDMul(val, ibuild.EmitLoadFReg(inst.FC));
|
||||
if (inst.SUBOP5 & 1)
|
||||
val = ibuild.EmitFDAdd(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
else
|
||||
val = ibuild.EmitFDSub(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
if (inst.SUBOP5 & 2)
|
||||
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);
|
||||
}
|
||||
|
||||
void Jit64::fmrx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(FloatingPoint)
|
||||
if (inst.Rc) {
|
||||
Default(inst); return;
|
||||
}
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FB);
|
||||
val = ibuild.EmitInsertDoubleInMReg(val, ibuild.EmitLoadFReg(inst.FD));
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
break;
|
||||
case 18: //div
|
||||
case 20: //sub
|
||||
val = ibuild.EmitFDSub(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
break;
|
||||
case 21: //add
|
||||
val = ibuild.EmitFDAdd(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
break;
|
||||
case 23: //sel
|
||||
case 24: //res
|
||||
default:
|
||||
_assert_msg_(DYNA_REC, 0, "fp_arith_s WTF!!!");
|
||||
}
|
||||
|
||||
void Jit64::fcmpx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(FloatingPoint)
|
||||
IREmitter::InstLoc lhs, rhs, res;
|
||||
lhs = ibuild.EmitLoadFRegDENToZero(inst.FA);
|
||||
rhs = ibuild.EmitLoadFRegDENToZero(inst.FB);
|
||||
res = ibuild.EmitFDCmpCR(lhs, rhs);
|
||||
ibuild.EmitStoreFPRF(res);
|
||||
ibuild.EmitStoreCR(res, inst.CRFD);
|
||||
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);
|
||||
}
|
||||
|
||||
void Jit64::fmaddXX(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(FloatingPoint)
|
||||
if (inst.Rc) {
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA);
|
||||
val = ibuild.EmitFDMul(val, ibuild.EmitLoadFReg(inst.FC));
|
||||
if (inst.SUBOP5 & 1)
|
||||
val = ibuild.EmitFDAdd(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
else
|
||||
val = ibuild.EmitFDSub(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
if (inst.SUBOP5 & 2)
|
||||
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);
|
||||
}
|
||||
|
||||
void Jit64::fmrx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(FloatingPoint)
|
||||
if (inst.Rc) {
|
||||
Default(inst); return;
|
||||
}
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FB);
|
||||
val = ibuild.EmitInsertDoubleInMReg(val, ibuild.EmitLoadFReg(inst.FD));
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
}
|
||||
|
||||
void Jit64::fcmpx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(FloatingPoint)
|
||||
IREmitter::InstLoc lhs, rhs, res;
|
||||
lhs = ibuild.EmitLoadFRegDENToZero(inst.FA);
|
||||
rhs = ibuild.EmitLoadFRegDENToZero(inst.FB);
|
||||
res = ibuild.EmitFDCmpCR(lhs, rhs);
|
||||
ibuild.EmitStoreFPRF(res);
|
||||
ibuild.EmitStoreCR(res, inst.CRFD);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,6 +41,7 @@
|
||||
void Jit64::lhax(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStore)
|
||||
IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB);
|
||||
if (inst.RA)
|
||||
@@ -53,6 +54,7 @@ void Jit64::lhax(UGeckoInstruction inst)
|
||||
void Jit64::lXz(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStore)
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16);
|
||||
if (inst.RA)
|
||||
@@ -73,6 +75,7 @@ void Jit64::lXz(UGeckoInstruction inst)
|
||||
void Jit64::lha(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStore)
|
||||
IREmitter::InstLoc addr =
|
||||
ibuild.EmitIntConst((s32)(s16)inst.SIMM_16);
|
||||
@@ -86,6 +89,7 @@ void Jit64::lha(UGeckoInstruction inst)
|
||||
void Jit64::lXzx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStore)
|
||||
IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB);
|
||||
if (inst.RA) {
|
||||
@@ -108,6 +112,8 @@ void Jit64::lXzx(UGeckoInstruction inst)
|
||||
void Jit64::dcbz(UGeckoInstruction inst)
|
||||
{
|
||||
Default(inst); return;
|
||||
|
||||
// TODO!
|
||||
#if 0
|
||||
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff)
|
||||
{Default(inst); return;} // turn off from debugger
|
||||
@@ -131,6 +137,7 @@ void Jit64::dcbz(UGeckoInstruction inst)
|
||||
void Jit64::stX(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStore)
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16),
|
||||
value = ibuild.EmitLoadGReg(inst.RS);
|
||||
@@ -150,6 +157,7 @@ void Jit64::stX(UGeckoInstruction inst)
|
||||
void Jit64::stXx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStore)
|
||||
IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB),
|
||||
value = ibuild.EmitLoadGReg(inst.RS);
|
||||
@@ -169,6 +177,7 @@ void Jit64::stXx(UGeckoInstruction inst)
|
||||
void Jit64::lmw(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStore)
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16);
|
||||
if (inst.RA)
|
||||
@@ -184,6 +193,7 @@ void Jit64::lmw(UGeckoInstruction inst)
|
||||
void Jit64::stmw(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStore)
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16);
|
||||
if (inst.RA)
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
void Jit64::lfs(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStoreFloating)
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16), val;
|
||||
if (inst.RA)
|
||||
@@ -58,6 +59,7 @@ void Jit64::lfs(UGeckoInstruction inst)
|
||||
void Jit64::lfd(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStoreFloating)
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16), val;
|
||||
if (inst.RA)
|
||||
@@ -72,6 +74,7 @@ void Jit64::lfd(UGeckoInstruction inst)
|
||||
void Jit64::stfd(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStoreFloating)
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16),
|
||||
val = ibuild.EmitLoadFReg(inst.RS);
|
||||
@@ -87,6 +90,7 @@ void Jit64::stfd(UGeckoInstruction inst)
|
||||
void Jit64::stfs(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStoreFloating)
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16),
|
||||
val = ibuild.EmitLoadFReg(inst.RS);
|
||||
@@ -103,6 +107,7 @@ void Jit64::stfs(UGeckoInstruction inst)
|
||||
void Jit64::stfsx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStoreFloating)
|
||||
IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB),
|
||||
val = ibuild.EmitLoadFReg(inst.RS);
|
||||
@@ -117,6 +122,7 @@ void Jit64::stfsx(UGeckoInstruction inst)
|
||||
void Jit64::lfsx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStoreFloating)
|
||||
IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB), val;
|
||||
if (inst.RA)
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
void Jit64::psq_st(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStorePaired)
|
||||
if (inst.W || !Core::GetStartupParameter().bOptimizeQuantizers) {Default(inst); return;}
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_12), val;
|
||||
@@ -59,6 +60,7 @@ void Jit64::psq_st(UGeckoInstruction inst)
|
||||
void Jit64::psq_l(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
DISABLE64
|
||||
JITDISABLE(LoadStorePaired)
|
||||
if (inst.W || !Core::GetStartupParameter().bOptimizeQuantizers) {Default(inst); return;}
|
||||
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_12), val;
|
||||
|
||||
@@ -26,193 +26,193 @@
|
||||
#include "Jit.h"
|
||||
#include "JitRegCache.h"
|
||||
|
||||
void Jit64::ps_mr(UGeckoInstruction inst)
|
||||
{
|
||||
void Jit64::ps_mr(UGeckoInstruction inst)
|
||||
{
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
void Jit64::ps_sel(UGeckoInstruction inst)
|
||||
{
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
void Jit64::ps_sign(UGeckoInstruction inst)
|
||||
{
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
void Jit64::ps_rsqrte(UGeckoInstruction inst)
|
||||
{
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
void Jit64::ps_arith(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Paired)
|
||||
if (inst.Rc || (inst.SUBOP5 != 21 && inst.SUBOP5 != 20 && inst.SUBOP5 != 25)) {
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
void Jit64::ps_sel(UGeckoInstruction inst)
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA), rhs;
|
||||
if (inst.SUBOP5 == 25)
|
||||
rhs = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
else
|
||||
rhs = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitCompactMRegToPacked(val);
|
||||
|
||||
switch (inst.SUBOP5)
|
||||
{
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
void Jit64::ps_sign(UGeckoInstruction inst)
|
||||
{
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
void Jit64::ps_rsqrte(UGeckoInstruction inst)
|
||||
{
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
void Jit64::ps_arith(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Paired)
|
||||
if (inst.Rc || (inst.SUBOP5 != 21 && inst.SUBOP5 != 20 && inst.SUBOP5 != 25)) {
|
||||
Default(inst); return;
|
||||
}
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA), rhs;
|
||||
if (inst.SUBOP5 == 25)
|
||||
rhs = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
else
|
||||
rhs = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitCompactMRegToPacked(val);
|
||||
|
||||
switch (inst.SUBOP5)
|
||||
{
|
||||
case 20:
|
||||
val = ibuild.EmitFPSub(val, rhs);
|
||||
break;
|
||||
case 21:
|
||||
val = ibuild.EmitFPAdd(val, rhs);
|
||||
break;
|
||||
case 25:
|
||||
val = ibuild.EmitFPMul(val, rhs);
|
||||
}
|
||||
val = ibuild.EmitExpandPackedToMReg(val);
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
}
|
||||
|
||||
void Jit64::ps_sum(UGeckoInstruction inst)
|
||||
{
|
||||
// FIXME: This operation strikes me as a bit strange...
|
||||
// perhaps we can optimize it depending on the users?
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Paired)
|
||||
if (inst.Rc || inst.SUBOP5 != 10) {
|
||||
Default(inst); return;
|
||||
}
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA), temp;
|
||||
val = ibuild.EmitCompactMRegToPacked(val);
|
||||
val = ibuild.EmitFPDup0(val);
|
||||
temp = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPAdd(val, temp);
|
||||
temp = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMerge11(val, temp);
|
||||
val = ibuild.EmitExpandPackedToMReg(val);
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
}
|
||||
|
||||
|
||||
void Jit64::ps_muls(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Paired)
|
||||
if (inst.Rc) {
|
||||
Default(inst); return;
|
||||
}
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA),
|
||||
rhs = ibuild.EmitLoadFReg(inst.FC);
|
||||
|
||||
val = ibuild.EmitCompactMRegToPacked(val);
|
||||
rhs = ibuild.EmitCompactMRegToPacked(rhs);
|
||||
|
||||
if (inst.SUBOP5 == 12)
|
||||
rhs = ibuild.EmitFPDup0(rhs);
|
||||
else
|
||||
rhs = ibuild.EmitFPDup1(rhs);
|
||||
|
||||
case 20:
|
||||
val = ibuild.EmitFPSub(val, rhs);
|
||||
break;
|
||||
case 21:
|
||||
val = ibuild.EmitFPAdd(val, rhs);
|
||||
break;
|
||||
case 25:
|
||||
val = ibuild.EmitFPMul(val, rhs);
|
||||
val = ibuild.EmitExpandPackedToMReg(val);
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
}
|
||||
val = ibuild.EmitExpandPackedToMReg(val);
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
}
|
||||
|
||||
void Jit64::ps_sum(UGeckoInstruction inst)
|
||||
{
|
||||
// FIXME: This operation strikes me as a bit strange...
|
||||
// perhaps we can optimize it depending on the users?
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Paired)
|
||||
if (inst.Rc || inst.SUBOP5 != 10) {
|
||||
Default(inst); return;
|
||||
}
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA), temp;
|
||||
val = ibuild.EmitCompactMRegToPacked(val);
|
||||
val = ibuild.EmitFPDup0(val);
|
||||
temp = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPAdd(val, temp);
|
||||
temp = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMerge11(val, temp);
|
||||
val = ibuild.EmitExpandPackedToMReg(val);
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
}
|
||||
|
||||
|
||||
void Jit64::ps_muls(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Paired)
|
||||
if (inst.Rc) {
|
||||
Default(inst); return;
|
||||
}
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA),
|
||||
rhs = ibuild.EmitLoadFReg(inst.FC);
|
||||
|
||||
val = ibuild.EmitCompactMRegToPacked(val);
|
||||
rhs = ibuild.EmitCompactMRegToPacked(rhs);
|
||||
|
||||
if (inst.SUBOP5 == 12)
|
||||
rhs = ibuild.EmitFPDup0(rhs);
|
||||
else
|
||||
rhs = ibuild.EmitFPDup1(rhs);
|
||||
|
||||
val = ibuild.EmitFPMul(val, rhs);
|
||||
val = ibuild.EmitExpandPackedToMReg(val);
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
}
|
||||
|
||||
|
||||
//TODO: find easy cases and optimize them, do a breakout like ps_arith
|
||||
void Jit64::ps_mergeXX(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Paired)
|
||||
if (inst.Rc) {
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
IREmitter::InstLoc val = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FA)),
|
||||
rhs = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
|
||||
//TODO: find easy cases and optimize them, do a breakout like ps_arith
|
||||
void Jit64::ps_mergeXX(UGeckoInstruction inst)
|
||||
switch (inst.SUBOP10)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Paired)
|
||||
if (inst.Rc) {
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
IREmitter::InstLoc val = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FA)),
|
||||
rhs = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
|
||||
switch (inst.SUBOP10)
|
||||
{
|
||||
case 528:
|
||||
val = ibuild.EmitFPMerge00(val, rhs);
|
||||
break; //00
|
||||
case 560:
|
||||
val = ibuild.EmitFPMerge01(val, rhs);
|
||||
break; //01
|
||||
case 592:
|
||||
val = ibuild.EmitFPMerge10(val, rhs);
|
||||
break; //10
|
||||
case 624:
|
||||
val = ibuild.EmitFPMerge11(val, rhs);
|
||||
break; //11
|
||||
default:
|
||||
_assert_msg_(DYNA_REC, 0, "ps_merge - invalid op");
|
||||
}
|
||||
val = ibuild.EmitExpandPackedToMReg(val);
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
case 528:
|
||||
val = ibuild.EmitFPMerge00(val, rhs);
|
||||
break; //00
|
||||
case 560:
|
||||
val = ibuild.EmitFPMerge01(val, rhs);
|
||||
break; //01
|
||||
case 592:
|
||||
val = ibuild.EmitFPMerge10(val, rhs);
|
||||
break; //10
|
||||
case 624:
|
||||
val = ibuild.EmitFPMerge11(val, rhs);
|
||||
break; //11
|
||||
default:
|
||||
_assert_msg_(DYNA_REC, 0, "ps_merge - invalid op");
|
||||
}
|
||||
val = ibuild.EmitExpandPackedToMReg(val);
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
}
|
||||
|
||||
|
||||
void Jit64::ps_maddXX(UGeckoInstruction inst)
|
||||
void Jit64::ps_maddXX(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Paired)
|
||||
if (inst.Rc) {
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA), op2, op3;
|
||||
val = ibuild.EmitCompactMRegToPacked(val);
|
||||
switch (inst.SUBOP5)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Paired)
|
||||
if (inst.Rc) {
|
||||
Default(inst); return;
|
||||
}
|
||||
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA), op2, op3;
|
||||
val = ibuild.EmitCompactMRegToPacked(val);
|
||||
switch (inst.SUBOP5)
|
||||
{
|
||||
case 14: {//madds0
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
op2 = ibuild.EmitFPDup0(op2);
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPAdd(val, op3);
|
||||
break;
|
||||
}
|
||||
case 15: {//madds1
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
op2 = ibuild.EmitFPDup1(op2);
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPAdd(val, op3);
|
||||
break;
|
||||
}
|
||||
case 28: {//msub
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPSub(val, op3);
|
||||
break;
|
||||
}
|
||||
case 29: {//madd
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPAdd(val, op3);
|
||||
break;
|
||||
}
|
||||
case 30: {//nmsub
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPSub(val, op3);
|
||||
val = ibuild.EmitFPNeg(val);
|
||||
break;
|
||||
}
|
||||
case 31: {//nmadd
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPAdd(val, op3);
|
||||
val = ibuild.EmitFPNeg(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
val = ibuild.EmitExpandPackedToMReg(val);
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
case 14: {//madds0
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
op2 = ibuild.EmitFPDup0(op2);
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPAdd(val, op3);
|
||||
break;
|
||||
}
|
||||
case 15: {//madds1
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
op2 = ibuild.EmitFPDup1(op2);
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPAdd(val, op3);
|
||||
break;
|
||||
}
|
||||
case 28: {//msub
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPSub(val, op3);
|
||||
break;
|
||||
}
|
||||
case 29: {//madd
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPAdd(val, op3);
|
||||
break;
|
||||
}
|
||||
case 30: {//nmsub
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPSub(val, op3);
|
||||
val = ibuild.EmitFPNeg(val);
|
||||
break;
|
||||
}
|
||||
case 31: {//nmadd
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPAdd(val, op3);
|
||||
val = ibuild.EmitFPNeg(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
val = ibuild.EmitExpandPackedToMReg(val);
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user