Skip to content

Commit

Permalink
[ARM] crand/crandc/creqv/crnand/crnor/cror/crorc/crxor/mcrf/mfcr/mtcr…
Browse files Browse the repository at this point in the history
…f/mtsr/mcrxr/mfsr implementations.
  • Loading branch information
Sonicadvance1 committed Sep 17, 2013
1 parent dcf74ef commit 302e9c8
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 14 deletions.
7 changes: 7 additions & 0 deletions Source/Core/Core/Src/PowerPC/JitArm32/Jit.h
Expand Up @@ -179,6 +179,13 @@ class JitArm : public JitBase, public ArmGen::ARMXCodeBlock
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);
Expand Down
181 changes: 181 additions & 0 deletions Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp
Expand Up @@ -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
Expand All @@ -98,6 +193,7 @@ void JitArm::mtmsr(UGeckoInstruction inst)

WriteExit(js.compilerPC + 4, 0);
}

void JitArm::mfmsr(UGeckoInstruction inst)
{
INSTRUCTION_START
Expand All @@ -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);
}
28 changes: 14 additions & 14 deletions Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp
Expand Up @@ -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}}
Expand Down Expand Up @@ -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}},
Expand Down

0 comments on commit 302e9c8

Please sign in to comment.