A64: Partially implement MRS

This commit is contained in:
MerryMage 2018-02-12 00:06:44 +00:00
parent bfd65bedfe
commit 8756487554
8 changed files with 48 additions and 2 deletions

View file

@ -107,6 +107,10 @@ struct UserConfig {
/// DCZID_EL0<4> is 0 if the DC ZVA instruction is permitted.
std::uint32_t dczid_el0 = 4;
/// Pointer to where TPIDRRO_EL0 is stored. This pointer will be inserted into
/// emitted code.
const std::uint64_t* tpidrro_el0 = nullptr;
// Determines whether AddTicks and GetTicksRemaining are called.
// If false, execution will continue until soon after Jit::HaltExecution is called.
// bool enable_ticks = true; // TODO

View file

@ -324,6 +324,23 @@ void A64EmitX64::EmitA64DataMemoryBarrier(A64EmitContext&, IR::Inst*) {
code.lfence();
}
void A64EmitX64::EmitA64GetDCZID(A64EmitContext& ctx, IR::Inst* inst) {
Xbyak::Reg32 result = ctx.reg_alloc.ScratchGpr().cvt32();
code.mov(result, conf.dczid_el0);
ctx.reg_alloc.DefineValue(inst, result);
}
void A64EmitX64::EmitA64GetTPIDRRO(A64EmitContext& ctx, IR::Inst* inst) {
Xbyak::Reg64 result = ctx.reg_alloc.ScratchGpr();
if (conf.tpidrro_el0) {
code.mov(result, u64(conf.tpidrro_el0));
code.mov(result, qword[result]);
} else {
code.xor_(result.cvt32(), result.cvt32());
}
ctx.reg_alloc.DefineValue(inst, result);
}
void A64EmitX64::EmitA64ReadMemory8(A64EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ctx.reg_alloc.HostCall(inst, {}, args[0]);

View file

@ -68,7 +68,7 @@ INST(DMB, "DMB", "11010
//INST(SYS, "SYS", "1101010100001oooNNNNMMMMooottttt")
//INST(MSR_reg, "MSR (register)", "110101010001poooNNNNMMMMooottttt")
//INST(SYSL, "SYSL", "1101010100101oooNNNNMMMMooottttt")
//INST(MRS, "MRS", "110101010011poooNNNNMMMMooottttt")
INST(MRS, "MRS", "110101010011poooNNNNMMMMooottttt")
// SYS: Data Cache
INST(DC_IVAC, "DC IVAC", "110101010000100001110110001ttttt")

View file

@ -53,6 +53,14 @@ void IREmitter::DataMemoryBarrier() {
Inst(Opcode::A64DataMemoryBarrier);
}
IR::U32 IREmitter::GetDCZID() {
return Inst<IR::U32>(Opcode::A64GetDCZID);
}
IR::U64 IREmitter::GetTPIDRRO() {
return Inst<IR::U64>(Opcode::A64GetTPIDRRO);
}
IR::U8 IREmitter::ReadMemory8(const IR::U64& vaddr) {
return Inst<IR::U8>(Opcode::A64ReadMemory8, vaddr);
}

View file

@ -44,6 +44,8 @@ public:
void DataCacheOperationRaised(DataCacheOperation op, const IR::U64& value);
void DataSynchronizationBarrier();
void DataMemoryBarrier();
IR::U32 GetDCZID();
IR::U64 GetTPIDRRO();
IR::U8 ReadMemory8(const IR::U64& vaddr);
IR::U16 ReadMemory16(const IR::U64& vaddr);

View file

@ -139,7 +139,7 @@ struct TranslatorVisitor final {
bool SYS(Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt);
bool MSR_reg(bool o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt);
bool SYSL(Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt);
bool MRS(bool o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt);
bool MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt);
// SYS: Data Cache
bool DC_IVAC(Reg Rt);

View file

@ -46,4 +46,17 @@ bool TranslatorVisitor::DMB(Imm<4> /*CRm*/) {
return true;
}
bool TranslatorVisitor::MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt) {
const size_t sys_reg = concatenate(Imm<1>{1}, o0, op1, CRn, CRm, op2).ZeroExtend<size_t>();
switch (sys_reg) {
case 0b11'011'1101'0000'011: // TPIDRRO_EL0
X(64, Rt, ir.GetTPIDRRO());
return true;
case 0b11'011'0000'0000'111: // DCZID_EL0
X(32, Rt, ir.GetDCZID());
return true;
}
return InterpretThisInstruction();
}
} // namespace Dynarmic::A64

View file

@ -61,6 +61,8 @@ A64OPC(ExceptionRaised, T::Void, T::U64, T::U64
A64OPC(DataCacheOperationRaised, T::Void, T::U64, T::U64 )
A64OPC(DataSynchronizationBarrier, T::Void, )
A64OPC(DataMemoryBarrier, T::Void, )
A64OPC(GetDCZID, T::U32, )
A64OPC(GetTPIDRRO, T::U64, )
// Hints
OPCODE(PushRSB, T::Void, T::U64 )