[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:
parent
0236ba3f86
commit
a0f2183424
|
@ -509,6 +509,21 @@ static void DoWriteCode(IRBuilder* ibuild, JitArmIL* Jit) {
|
||||||
Jit->BL(R14);
|
Jit->BL(R14);
|
||||||
break;
|
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: {
|
case RFIExit: {
|
||||||
const u32 mask = 0x87C0FFFF;
|
const u32 mask = 0x87C0FFFF;
|
||||||
const u32 clearMSR13 = 0xFFFBFFFF; // Mask used to clear the bit MSR[13]
|
const u32 clearMSR13 = 0xFFFBFFFF; // Mask used to clear the bit MSR[13]
|
||||||
|
|
|
@ -70,6 +70,11 @@ void JitArmIL::DoNothing(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
// Yup, just don't do anything.
|
// Yup, just don't do anything.
|
||||||
}
|
}
|
||||||
|
void JitArmIL::Break(UGeckoInstruction _inst)
|
||||||
|
{
|
||||||
|
ibuild.EmitINT3();
|
||||||
|
}
|
||||||
|
|
||||||
void JitArmIL::DoDownCount()
|
void JitArmIL::DoDownCount()
|
||||||
{
|
{
|
||||||
ARMReg rA = R14;
|
ARMReg rA = R14;
|
||||||
|
@ -105,7 +110,13 @@ void JitArmIL::WriteRfiExitDestInR(ARMReg Reg)
|
||||||
MOVI2R(Reg, (u32)asm_routines.testExceptions);
|
MOVI2R(Reg, (u32)asm_routines.testExceptions);
|
||||||
B(Reg);
|
B(Reg);
|
||||||
}
|
}
|
||||||
|
void JitArmIL::WriteExceptionExit()
|
||||||
|
{
|
||||||
|
DoDownCount();
|
||||||
|
|
||||||
|
MOVI2R(R14, (u32)asm_routines.testExceptions);
|
||||||
|
B(R14);
|
||||||
|
}
|
||||||
void JitArmIL::WriteExit(u32 destination, int exit_num)
|
void JitArmIL::WriteExit(u32 destination, int exit_num)
|
||||||
{
|
{
|
||||||
DoDownCount();
|
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)
|
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();
|
int blockSize = code_buf->GetSize();
|
||||||
// Memory exception on instruction fetch
|
// Memory exception on instruction fetch
|
||||||
bool memory_exception = false;
|
bool memory_exception = false;
|
||||||
|
@ -318,7 +328,7 @@ const u8* JitArmIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
|
||||||
}
|
}
|
||||||
if (!ops[i].skip)
|
if (!ops[i].skip)
|
||||||
{
|
{
|
||||||
PrintDebug(ops[i].inst, 1);
|
PrintDebug(ops[i].inst, 0);
|
||||||
if (js.memcheck && (opinfo->flags & FL_USE_FPU))
|
if (js.memcheck && (opinfo->flags & FL_USE_FPU))
|
||||||
{
|
{
|
||||||
// Don't do this yet
|
// 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();
|
FlushIcache();
|
||||||
return start;
|
return start;
|
||||||
|
|
||||||
|
|
|
@ -75,12 +75,14 @@ public:
|
||||||
void WriteExit(u32 destination, int exit_num);
|
void WriteExit(u32 destination, int exit_num);
|
||||||
void WriteExitDestInReg(ARMReg Reg);
|
void WriteExitDestInReg(ARMReg Reg);
|
||||||
void WriteRfiExitDestInR(ARMReg Reg);
|
void WriteRfiExitDestInR(ARMReg Reg);
|
||||||
|
void WriteExceptionExit();
|
||||||
|
|
||||||
// OPCODES
|
// OPCODES
|
||||||
void unknown_instruction(UGeckoInstruction inst);
|
void unknown_instruction(UGeckoInstruction inst);
|
||||||
void Default(UGeckoInstruction inst);
|
void Default(UGeckoInstruction inst);
|
||||||
void DoNothing(UGeckoInstruction inst);
|
void DoNothing(UGeckoInstruction inst);
|
||||||
void HLEFunction(UGeckoInstruction inst);
|
void HLEFunction(UGeckoInstruction inst);
|
||||||
|
void Break(UGeckoInstruction inst);
|
||||||
|
|
||||||
void DynaRunTable4(UGeckoInstruction inst);
|
void DynaRunTable4(UGeckoInstruction inst);
|
||||||
void DynaRunTable19(UGeckoInstruction inst);
|
void DynaRunTable19(UGeckoInstruction inst);
|
||||||
|
@ -94,10 +96,13 @@ public:
|
||||||
void BIN_ADD(ARMReg reg, Operand2 op2);
|
void BIN_ADD(ARMReg reg, Operand2 op2);
|
||||||
|
|
||||||
// Branches
|
// Branches
|
||||||
|
void icbi(UGeckoInstruction inst);
|
||||||
|
void sc(UGeckoInstruction inst);
|
||||||
void rfi(UGeckoInstruction inst);
|
void rfi(UGeckoInstruction inst);
|
||||||
void bx(UGeckoInstruction inst);
|
void bx(UGeckoInstruction inst);
|
||||||
void bcx(UGeckoInstruction inst);
|
void bcx(UGeckoInstruction inst);
|
||||||
void bclrx(UGeckoInstruction inst);
|
void bclrx(UGeckoInstruction inst);
|
||||||
|
void bcctrx(UGeckoInstruction inst);
|
||||||
// System Registers
|
// System Registers
|
||||||
void mtmsr(UGeckoInstruction inst);
|
void mtmsr(UGeckoInstruction inst);
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,8 +12,17 @@
|
||||||
|
|
||||||
#include "../../HW/Memmap.h"
|
#include "../../HW/Memmap.h"
|
||||||
|
|
||||||
//#define NORMALBRANCH_START Default(inst); ibuild.EmitInterpreterBranch(); return;
|
#define NORMALBRANCH_START Default(inst); ibuild.EmitInterpreterBranch(); return;
|
||||||
#define NORMALBRANCH_START
|
//#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)
|
void JitArmIL::rfi(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
@ -143,3 +152,32 @@ void JitArmIL::bcx(UGeckoInstruction inst)
|
||||||
ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4));
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,10 @@ static GekkoOPTemplate primarytable[] =
|
||||||
{16, &JitArmIL::bcx}, //"bcx", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
{16, &JitArmIL::bcx}, //"bcx", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
||||||
{18, &JitArmIL::bx}, //"bx", 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}},
|
{2, &JitArmIL::Default}, //"DynaBlock", OPTYPE_SYSTEM, 0}},
|
||||||
{3, &JitArmIL::Default}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
{3, &JitArmIL::Break}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
||||||
{17, &JitArmIL::Default}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
|
{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}},
|
{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}},
|
{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[] =
|
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}},
|
{16, &JitArmIL::bclrx}, //"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}},
|
||||||
{257, &JitArmIL::Default}, //"crand", OPTYPE_CR, FL_EVIL}},
|
{257, &JitArmIL::Default}, //"crand", OPTYPE_CR, FL_EVIL}},
|
||||||
{129, &JitArmIL::Default}, //"crandc", 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}},
|
{0, &JitArmIL::Default}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}},
|
||||||
|
|
||||||
{50, &JitArmIL::rfi}, //"rfi", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS, 1}},
|
{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}},
|
{595, &JitArmIL::Default}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
||||||
{659, &JitArmIL::Default}, //"mfsrin", 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}},
|
{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
|
// Unused instructions on GC
|
||||||
{310, &JitArmIL::Default}, //"eciwx", OPTYPE_INTEGER, FL_RC_BIT}},
|
{310, &JitArmIL::Default}, //"eciwx", OPTYPE_INTEGER, FL_RC_BIT}},
|
||||||
|
|
Loading…
Reference in New Issue