[ARM] crand/crandc/creqv/crnand/crnor/cror/crorc/crxor/mcrf/mfcr/mtcrf/mtsr/mcrxr/mfsr implementations.

This commit is contained in:
Ryan Houdek 2013-09-17 10:59:12 +00:00
parent dcf74ef2b3
commit 302e9c891b
3 changed files with 202 additions and 14 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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}},