mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
[ARM] crand/crandc/creqv/crnand/crnor/cror/crorc/crxor/mcrf/mfcr/mtcrf/mtsr/mcrxr/mfsr implementations.
This commit is contained in:
parent
dcf74ef2b3
commit
302e9c891b
@ -179,6 +179,13 @@ public:
|
||||
void mtspr(UGeckoInstruction _inst);
|
||||
void mfspr(UGeckoInstruction _inst);
|
||||
void mftb(UGeckoInstruction _inst);
|
||||
void crXXX(UGeckoInstruction _inst);
|
||||
void mcrf(UGeckoInstruction _inst);
|
||||
void mfcr(UGeckoInstruction _inst);
|
||||
void mtcrf(UGeckoInstruction _inst);
|
||||
void mtsr(UGeckoInstruction _inst);
|
||||
void mfsr(UGeckoInstruction _inst);
|
||||
void mcrxr(UGeckoInstruction _inst);
|
||||
|
||||
// LoadStore
|
||||
void stX(UGeckoInstruction _inst);
|
||||
|
@ -85,6 +85,101 @@ void JitArm::mfspr(UGeckoInstruction inst)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JitArm::mfcr(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff)
|
||||
// USES_CR
|
||||
ARMReg rA = gpr.GetReg();
|
||||
ARMReg rB = gpr.GetReg();
|
||||
int d = inst.RD;
|
||||
LDRB(rA, R9, PPCSTATE_OFF(cr_fast[0]));
|
||||
|
||||
for (int i = 1; i < 8; i++)
|
||||
{
|
||||
LDRB(rB, R9, PPCSTATE_OFF(cr_fast[i]));
|
||||
LSL(rA, rA, 4);
|
||||
ORR(rA, rA, rB);
|
||||
}
|
||||
MOV(gpr.R(d), rA);
|
||||
gpr.Unlock(rA, rB);
|
||||
}
|
||||
|
||||
void JitArm::mtcrf(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff)
|
||||
ARMReg rA = gpr.GetReg();
|
||||
|
||||
// USES_CR
|
||||
u32 crm = inst.CRM;
|
||||
if (crm != 0)
|
||||
{
|
||||
if (gpr.IsImm(inst.RS))
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((crm & (0x80 >> i)) != 0)
|
||||
{
|
||||
u8 newcr = (gpr.GetImm(inst.RS) >> (28 - (i * 4))) & 0xF;
|
||||
MOV(rA, newcr);
|
||||
STRB(rA, R9, PPCSTATE_OFF(cr_fast[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((crm & (0x80 >> i)) != 0)
|
||||
{
|
||||
MOV(rA, gpr.R(inst.RS));
|
||||
LSR(rA, rA, 28 - (i * 4));
|
||||
AND(rA, rA, 0xF);
|
||||
STRB(rA, R9, PPCSTATE_OFF(cr_fast[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
|
||||
void JitArm::mtsr(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff)
|
||||
|
||||
STR(gpr.R(inst.RS), R9, PPCSTATE_OFF(sr[inst.SR]));
|
||||
}
|
||||
|
||||
void JitArm::mfsr(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff)
|
||||
|
||||
LDR(gpr.R(inst.RD), R9, PPCSTATE_OFF(sr[inst.SR]));
|
||||
}
|
||||
void JitArm::mcrxr(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff)
|
||||
|
||||
ARMReg rA = gpr.GetReg();
|
||||
ARMReg rB = gpr.GetReg();
|
||||
// Copy XER[0-3] into CR[inst.CRFD]
|
||||
LDR(rA, R9, PPCSTATE_OFF(spr[SPR_XER]));
|
||||
MOV(rB, rA);
|
||||
LSR(rA, rA, 28);
|
||||
STRB(rA, R9, PPCSTATE_OFF(cr_fast[inst.CRFD]));
|
||||
|
||||
// Clear XER[0-3]
|
||||
Operand2 Top4(0xF, 2);
|
||||
BIC(rB, rB, Top4);
|
||||
STR(rB, R9, PPCSTATE_OFF(spr[SPR_XER]));
|
||||
gpr.Unlock(rA, rB);
|
||||
}
|
||||
|
||||
void JitArm::mtmsr(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
@ -98,6 +193,7 @@ void JitArm::mtmsr(UGeckoInstruction inst)
|
||||
|
||||
WriteExit(js.compilerPC + 4, 0);
|
||||
}
|
||||
|
||||
void JitArm::mfmsr(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
@ -106,3 +202,88 @@ void JitArm::mfmsr(UGeckoInstruction inst)
|
||||
LDR(gpr.R(inst.RD), R9, PPCSTATE_OFF(msr));
|
||||
}
|
||||
|
||||
void JitArm::mcrf(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff)
|
||||
ARMReg rA = gpr.GetReg();
|
||||
|
||||
if (inst.CRFS != inst.CRFD)
|
||||
{
|
||||
LDRB(rA, R9, PPCSTATE_OFF(cr_fast[inst.CRFS]));
|
||||
STRB(rA, R9, PPCSTATE_OFF(cr_fast[inst.CRFD]));
|
||||
}
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
|
||||
void JitArm::crXXX(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff)
|
||||
|
||||
ARMReg rA = gpr.GetReg();
|
||||
ARMReg rB = gpr.GetReg();
|
||||
// Get bit CRBA aligned with bit CRBD
|
||||
LDRB(rA, R9, PPCSTATE_OFF(cr_fast[inst.CRBA >> 2]));
|
||||
int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3);
|
||||
if (shiftA < 0)
|
||||
LSL(rA, rA, -shiftA);
|
||||
else if (shiftA > 0)
|
||||
LSR(rA, rA, shiftA);
|
||||
|
||||
// Get bit CRBB aligned with bit CRBD
|
||||
int shiftB = (inst.CRBD & 3) - (inst.CRBB & 3);
|
||||
LDRB(rB, R9, PPCSTATE_OFF(cr_fast[inst.CRBB >> 2]));
|
||||
if (shiftB < 0)
|
||||
LSL(rB, rB, -shiftB);
|
||||
else if (shiftB > 0)
|
||||
LSR(rB, rB, shiftB);
|
||||
|
||||
// Compute combined bit
|
||||
switch(inst.SUBOP10)
|
||||
{
|
||||
case 33: // crnor
|
||||
ORR(rA, rA, rB);
|
||||
RBIT(rA, rA);
|
||||
break;
|
||||
|
||||
case 129: // crandc
|
||||
RBIT(rB, rB);
|
||||
AND(rA, rA, rB);
|
||||
break;
|
||||
|
||||
case 193: // crxor
|
||||
EOR(rA, rA, rB);
|
||||
break;
|
||||
|
||||
case 225: // crnand
|
||||
AND(rA, rA, rB);
|
||||
RBIT(rA, rA);
|
||||
break;
|
||||
|
||||
case 257: // crand
|
||||
AND(rA, rA, rB);
|
||||
break;
|
||||
|
||||
case 289: // creqv
|
||||
EOR(rA, rA, rB);
|
||||
RBIT(rA, rA);
|
||||
break;
|
||||
|
||||
case 417: // crorc
|
||||
RBIT(rB, rB);
|
||||
ORR(rA, rA, rB);
|
||||
break;
|
||||
|
||||
case 449: // cror
|
||||
ORR(rA, rA, rB);
|
||||
break;
|
||||
}
|
||||
// Store result bit in CRBD
|
||||
AND(rA, rA, 0x8 >> (inst.CRBD & 3));
|
||||
LDRB(rB, R9, PPCSTATE_OFF(cr_fast[inst.CRBD >> 2]));
|
||||
BIC(rB, rB, 0x8 >> (inst.CRBD & 3));
|
||||
ORR(rB, rB, rA);
|
||||
STRB(rB, R9, PPCSTATE_OFF(cr_fast[inst.CRBD >> 2]));
|
||||
gpr.Unlock(rA, rB);
|
||||
}
|
||||
|
@ -175,17 +175,17 @@ static GekkoOPTemplate table19[] =
|
||||
{
|
||||
{528, &JitArm::bcctrx}, //"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}},
|
||||
{16, &JitArm::bclrx}, //"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}},
|
||||
{257, &JitArm::Default}, //"crand", OPTYPE_CR, FL_EVIL}},
|
||||
{129, &JitArm::Default}, //"crandc", OPTYPE_CR, FL_EVIL}},
|
||||
{289, &JitArm::Default}, //"creqv", OPTYPE_CR, FL_EVIL}},
|
||||
{225, &JitArm::Default}, //"crnand", OPTYPE_CR, FL_EVIL}},
|
||||
{33, &JitArm::Default}, //"crnor", OPTYPE_CR, FL_EVIL}},
|
||||
{449, &JitArm::Default}, //"cror", OPTYPE_CR, FL_EVIL}},
|
||||
{417, &JitArm::Default}, //"crorc", OPTYPE_CR, FL_EVIL}},
|
||||
{193, &JitArm::Default}, //"crxor", OPTYPE_CR, FL_EVIL}},
|
||||
{257, &JitArm::crXXX}, //"crand", OPTYPE_CR, FL_EVIL}},
|
||||
{129, &JitArm::crXXX}, //"crandc", OPTYPE_CR, FL_EVIL}},
|
||||
{289, &JitArm::crXXX}, //"creqv", OPTYPE_CR, FL_EVIL}},
|
||||
{225, &JitArm::crXXX}, //"crnand", OPTYPE_CR, FL_EVIL}},
|
||||
{33, &JitArm::crXXX}, //"crnor", OPTYPE_CR, FL_EVIL}},
|
||||
{449, &JitArm::crXXX}, //"cror", OPTYPE_CR, FL_EVIL}},
|
||||
{417, &JitArm::crXXX}, //"crorc", OPTYPE_CR, FL_EVIL}},
|
||||
{193, &JitArm::crXXX}, //"crxor", OPTYPE_CR, FL_EVIL}},
|
||||
|
||||
{150, &JitArm::DoNothing}, //"isync", OPTYPE_ICACHE, FL_EVIL}},
|
||||
{0, &JitArm::Default}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}},
|
||||
{0, &JitArm::mcrf}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}},
|
||||
|
||||
{50, &JitArm::rfi}, //"rfi", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS, 1}},
|
||||
{18, &JitArm::Break}, //"rfid", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS}}
|
||||
@ -279,17 +279,17 @@ static GekkoOPTemplate table31[] =
|
||||
{759, &JitArm::Default}, //"stfdux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}},
|
||||
{983, &JitArm::Default}, //"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
|
||||
|
||||
{19, &JitArm::Default}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}},
|
||||
{19, &JitArm::mfcr}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}},
|
||||
{83, &JitArm::mfmsr}, //"mfmsr", OPTYPE_SYSTEM, FL_OUT_D}},
|
||||
{144, &JitArm::Default}, //"mtcrf", OPTYPE_SYSTEM, 0}},
|
||||
{144, &JitArm::mtcrf}, //"mtcrf", OPTYPE_SYSTEM, 0}},
|
||||
{146, &JitArm::mtmsr}, //"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
||||
{210, &JitArm::Default}, //"mtsr", OPTYPE_SYSTEM, 0}},
|
||||
{210, &JitArm::mtsr}, //"mtsr", OPTYPE_SYSTEM, 0}},
|
||||
{242, &JitArm::Default}, //"mtsrin", OPTYPE_SYSTEM, 0}},
|
||||
{339, &JitArm::mfspr}, //"mfspr", OPTYPE_SPR, FL_OUT_D}},
|
||||
{467, &JitArm::mtspr}, //"mtspr", OPTYPE_SPR, 0, 2}},
|
||||
{371, &JitArm::mftb}, //"mftb", OPTYPE_SYSTEM, FL_OUT_D | FL_TIMER}},
|
||||
{512, &JitArm::Default}, //"mcrxr", OPTYPE_SYSTEM, 0}},
|
||||
{595, &JitArm::Default}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
||||
{512, &JitArm::mcrxr}, //"mcrxr", OPTYPE_SYSTEM, 0}},
|
||||
{595, &JitArm::mfsr}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
||||
{659, &JitArm::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
||||
|
||||
{4, &JitArm::Break}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
|
||||
|
Loading…
Reference in New Issue
Block a user