A64: Partially implement MRS
This commit is contained in:
parent
bfd65bedfe
commit
8756487554
8 changed files with 48 additions and 2 deletions
|
@ -107,6 +107,10 @@ struct UserConfig {
|
||||||
/// DCZID_EL0<4> is 0 if the DC ZVA instruction is permitted.
|
/// DCZID_EL0<4> is 0 if the DC ZVA instruction is permitted.
|
||||||
std::uint32_t dczid_el0 = 4;
|
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.
|
// Determines whether AddTicks and GetTicksRemaining are called.
|
||||||
// If false, execution will continue until soon after Jit::HaltExecution is called.
|
// If false, execution will continue until soon after Jit::HaltExecution is called.
|
||||||
// bool enable_ticks = true; // TODO
|
// bool enable_ticks = true; // TODO
|
||||||
|
|
|
@ -324,6 +324,23 @@ void A64EmitX64::EmitA64DataMemoryBarrier(A64EmitContext&, IR::Inst*) {
|
||||||
code.lfence();
|
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) {
|
void A64EmitX64::EmitA64ReadMemory8(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.HostCall(inst, {}, args[0]);
|
ctx.reg_alloc.HostCall(inst, {}, args[0]);
|
||||||
|
|
|
@ -68,7 +68,7 @@ INST(DMB, "DMB", "11010
|
||||||
//INST(SYS, "SYS", "1101010100001oooNNNNMMMMooottttt")
|
//INST(SYS, "SYS", "1101010100001oooNNNNMMMMooottttt")
|
||||||
//INST(MSR_reg, "MSR (register)", "110101010001poooNNNNMMMMooottttt")
|
//INST(MSR_reg, "MSR (register)", "110101010001poooNNNNMMMMooottttt")
|
||||||
//INST(SYSL, "SYSL", "1101010100101oooNNNNMMMMooottttt")
|
//INST(SYSL, "SYSL", "1101010100101oooNNNNMMMMooottttt")
|
||||||
//INST(MRS, "MRS", "110101010011poooNNNNMMMMooottttt")
|
INST(MRS, "MRS", "110101010011poooNNNNMMMMooottttt")
|
||||||
|
|
||||||
// SYS: Data Cache
|
// SYS: Data Cache
|
||||||
INST(DC_IVAC, "DC IVAC", "110101010000100001110110001ttttt")
|
INST(DC_IVAC, "DC IVAC", "110101010000100001110110001ttttt")
|
||||||
|
|
|
@ -53,6 +53,14 @@ void IREmitter::DataMemoryBarrier() {
|
||||||
Inst(Opcode::A64DataMemoryBarrier);
|
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) {
|
IR::U8 IREmitter::ReadMemory8(const IR::U64& vaddr) {
|
||||||
return Inst<IR::U8>(Opcode::A64ReadMemory8, vaddr);
|
return Inst<IR::U8>(Opcode::A64ReadMemory8, vaddr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,8 @@ public:
|
||||||
void DataCacheOperationRaised(DataCacheOperation op, const IR::U64& value);
|
void DataCacheOperationRaised(DataCacheOperation op, const IR::U64& value);
|
||||||
void DataSynchronizationBarrier();
|
void DataSynchronizationBarrier();
|
||||||
void DataMemoryBarrier();
|
void DataMemoryBarrier();
|
||||||
|
IR::U32 GetDCZID();
|
||||||
|
IR::U64 GetTPIDRRO();
|
||||||
|
|
||||||
IR::U8 ReadMemory8(const IR::U64& vaddr);
|
IR::U8 ReadMemory8(const IR::U64& vaddr);
|
||||||
IR::U16 ReadMemory16(const IR::U64& vaddr);
|
IR::U16 ReadMemory16(const IR::U64& vaddr);
|
||||||
|
|
|
@ -139,7 +139,7 @@ struct TranslatorVisitor final {
|
||||||
bool SYS(Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt);
|
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 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 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
|
// SYS: Data Cache
|
||||||
bool DC_IVAC(Reg Rt);
|
bool DC_IVAC(Reg Rt);
|
||||||
|
|
|
@ -46,4 +46,17 @@ bool TranslatorVisitor::DMB(Imm<4> /*CRm*/) {
|
||||||
return true;
|
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
|
} // namespace Dynarmic::A64
|
||||||
|
|
|
@ -61,6 +61,8 @@ A64OPC(ExceptionRaised, T::Void, T::U64, T::U64
|
||||||
A64OPC(DataCacheOperationRaised, T::Void, T::U64, T::U64 )
|
A64OPC(DataCacheOperationRaised, T::Void, T::U64, T::U64 )
|
||||||
A64OPC(DataSynchronizationBarrier, T::Void, )
|
A64OPC(DataSynchronizationBarrier, T::Void, )
|
||||||
A64OPC(DataMemoryBarrier, T::Void, )
|
A64OPC(DataMemoryBarrier, T::Void, )
|
||||||
|
A64OPC(GetDCZID, T::U32, )
|
||||||
|
A64OPC(GetTPIDRRO, T::U64, )
|
||||||
|
|
||||||
// Hints
|
// Hints
|
||||||
OPCODE(PushRSB, T::Void, T::U64 )
|
OPCODE(PushRSB, T::Void, T::U64 )
|
||||||
|
|
Loading…
Reference in a new issue