[ARM-JITArmIL] Provide the necessary instructions to allow the JitArmIL to actually run. Disable branch instructions as well for now since one is wrong somewhere.

This commit is contained in:
Ryan Houdek 2013-10-08 16:42:33 +00:00
parent 0236ba3f86
commit a0f2183424
5 changed files with 79 additions and 12 deletions

View file

@ -509,6 +509,21 @@ static void DoWriteCode(IRBuilder* ibuild, JitArmIL* Jit) {
Jit->BL(R14);
break;
}
case SystemCall: {
unsigned InstLoc = ibuild->GetImmValue(getOp1(I));
Jit->MOVI2R(R14, InstLoc + 4);
Jit->STR(R14, R9, PPCSTATE_OFF(pc));
Jit->LDR(R14, R9, PPCSTATE_OFF(Exceptions));
Jit->ORR(R14, R14, EXCEPTION_SYSCALL);
Jit->STR(R14, R9, PPCSTATE_OFF(Exceptions));
Jit->WriteExceptionExit();
break;
}
case InterpreterBranch: {
Jit->LDR(R14, R9, PPCSTATE_OFF(npc));
Jit->WriteExitDestInReg(R14);
break;
}
case RFIExit: {
const u32 mask = 0x87C0FFFF;
const u32 clearMSR13 = 0xFFFBFFFF; // Mask used to clear the bit MSR[13]

View file

@ -70,6 +70,11 @@ void JitArmIL::DoNothing(UGeckoInstruction _inst)
{
// Yup, just don't do anything.
}
void JitArmIL::Break(UGeckoInstruction _inst)
{
ibuild.EmitINT3();
}
void JitArmIL::DoDownCount()
{
ARMReg rA = R14;
@ -105,7 +110,13 @@ void JitArmIL::WriteRfiExitDestInR(ARMReg Reg)
MOVI2R(Reg, (u32)asm_routines.testExceptions);
B(Reg);
}
void JitArmIL::WriteExceptionExit()
{
DoDownCount();
MOVI2R(R14, (u32)asm_routines.testExceptions);
B(R14);
}
void JitArmIL::WriteExit(u32 destination, int exit_num)
{
DoDownCount();
@ -183,7 +194,6 @@ void STACKALIGN JitArmIL::Jit(u32 em_address)
const u8* JitArmIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlock *b)
{
printf("Doing a JIT in JITARMIL. Scream and shout.\n");
int blockSize = code_buf->GetSize();
// Memory exception on instruction fetch
bool memory_exception = false;
@ -318,7 +328,7 @@ const u8* JitArmIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
}
if (!ops[i].skip)
{
PrintDebug(ops[i].inst, 1);
PrintDebug(ops[i].inst, 0);
if (js.memcheck && (opinfo->flags & FL_USE_FPU))
{
// Don't do this yet
@ -349,7 +359,6 @@ const u8* JitArmIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
{
}
printf("Done emitting block. size was 0x%08x\n", size);
FlushIcache();
return start;

View file

@ -75,12 +75,14 @@ public:
void WriteExit(u32 destination, int exit_num);
void WriteExitDestInReg(ARMReg Reg);
void WriteRfiExitDestInR(ARMReg Reg);
void WriteExceptionExit();
// OPCODES
void unknown_instruction(UGeckoInstruction inst);
void Default(UGeckoInstruction inst);
void DoNothing(UGeckoInstruction inst);
void HLEFunction(UGeckoInstruction inst);
void Break(UGeckoInstruction inst);
void DynaRunTable4(UGeckoInstruction inst);
void DynaRunTable19(UGeckoInstruction inst);
@ -94,10 +96,13 @@ public:
void BIN_ADD(ARMReg reg, Operand2 op2);
// Branches
void icbi(UGeckoInstruction inst);
void sc(UGeckoInstruction inst);
void rfi(UGeckoInstruction inst);
void bx(UGeckoInstruction inst);
void bcx(UGeckoInstruction inst);
void bclrx(UGeckoInstruction inst);
void bcctrx(UGeckoInstruction inst);
// System Registers
void mtmsr(UGeckoInstruction inst);
};

View file

@ -12,8 +12,17 @@
#include "../../HW/Memmap.h"
//#define NORMALBRANCH_START Default(inst); ibuild.EmitInterpreterBranch(); return;
#define NORMALBRANCH_START
#define NORMALBRANCH_START Default(inst); ibuild.EmitInterpreterBranch(); return;
//#define NORMALBRANCH_START
void JitArmIL::icbi(UGeckoInstruction inst)
{
Default(inst);
ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4));
}
void JitArmIL::sc(UGeckoInstruction inst)
{
ibuild.EmitSystemCall(ibuild.EmitIntConst(js.compilerPC));
}
void JitArmIL::rfi(UGeckoInstruction inst)
{
@ -143,3 +152,32 @@ void JitArmIL::bcx(UGeckoInstruction inst)
ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4));
}
void JitArmIL::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);
}

View file

@ -40,10 +40,10 @@ static GekkoOPTemplate primarytable[] =
{16, &JitArmIL::bcx}, //"bcx", OPTYPE_SYSTEM, FL_ENDBLOCK}},
{18, &JitArmIL::bx}, //"bx", OPTYPE_SYSTEM, FL_ENDBLOCK}},
{1, &JitArmIL::Default}, //"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}},
{1, &JitArmIL::HLEFunction}, //"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}},
{2, &JitArmIL::Default}, //"DynaBlock", OPTYPE_SYSTEM, 0}},
{3, &JitArmIL::Default}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}},
{17, &JitArmIL::Default}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
{3, &JitArmIL::Break}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}},
{17, &JitArmIL::sc}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
{7, &JitArmIL::Default}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}},
{8, &JitArmIL::Default}, //"subfic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}},
@ -160,7 +160,7 @@ static GekkoOPTemplate table4_3[] =
static GekkoOPTemplate table19[] =
{
{528, &JitArmIL::Default}, //"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}},
{528, &JitArmIL::bcctrx}, //"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}},
{16, &JitArmIL::bclrx}, //"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}},
{257, &JitArmIL::Default}, //"crand", OPTYPE_CR, FL_EVIL}},
{129, &JitArmIL::Default}, //"crandc", OPTYPE_CR, FL_EVIL}},
@ -175,7 +175,7 @@ static GekkoOPTemplate table19[] =
{0, &JitArmIL::Default}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}},
{50, &JitArmIL::rfi}, //"rfi", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS, 1}},
{18, &JitArmIL::Default}, //"rfid", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS}}
{18, &JitArmIL::Break}, //"rfid", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS}}
};
@ -279,9 +279,9 @@ static GekkoOPTemplate table31[] =
{595, &JitArmIL::Default}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}},
{659, &JitArmIL::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}},
{4, &JitArmIL::Default}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
{4, &JitArmIL::Break}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
{598, &JitArmIL::Default}, //"sync", OPTYPE_SYSTEM, 0, 2}},
{982, &JitArmIL::Default}, //"icbi", OPTYPE_SYSTEM, FL_ENDBLOCK, 3}},
{982, &JitArmIL::icbi}, //"icbi", OPTYPE_SYSTEM, FL_ENDBLOCK, 3}},
// Unused instructions on GC
{310, &JitArmIL::Default}, //"eciwx", OPTYPE_INTEGER, FL_RC_BIT}},