mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-03-06 02:26:30 +00:00
A64: Implement ISB
Given we want to ensure that all instructions are fetched again, we can treat an ISB instruction as a code cache flush.
This commit is contained in:
@@ -64,7 +64,7 @@ INST(SEVL, "SEVL", "11010
|
||||
INST(CLREX, "CLREX", "11010101000000110011MMMM01011111")
|
||||
INST(DSB, "DSB", "11010101000000110011MMMM10011111")
|
||||
INST(DMB, "DMB", "11010101000000110011MMMM10111111")
|
||||
//INST(ISB, "ISB", "11010101000000110011MMMM11011111")
|
||||
INST(ISB, "ISB", "11010101000000110011MMMM11011111")
|
||||
//INST(SYS, "SYS", "1101010100001oooNNNNMMMMooottttt")
|
||||
INST(MSR_reg, "MSR (register)", "110101010001poooNNNNMMMMooottttt")
|
||||
//INST(SYSL, "SYSL", "1101010100101oooNNNNMMMMooottttt")
|
||||
|
||||
@@ -57,6 +57,10 @@ void IREmitter::DataMemoryBarrier() {
|
||||
Inst(Opcode::A64DataMemoryBarrier);
|
||||
}
|
||||
|
||||
void IREmitter::InstructionSynchronizationBarrier() {
|
||||
Inst(Opcode::A64InstructionSynchronizationBarrier);
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::GetCNTFRQ() {
|
||||
return Inst<IR::U32>(Opcode::A64GetCNTFRQ);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
void DataCacheOperationRaised(DataCacheOperation op, const IR::U64& value);
|
||||
void DataSynchronizationBarrier();
|
||||
void DataMemoryBarrier();
|
||||
void InstructionSynchronizationBarrier();
|
||||
IR::U32 GetCNTFRQ();
|
||||
IR::U64 GetCNTPCT(); // TODO: Ensure sub-basic-block cycle counts are updated before this.
|
||||
IR::U32 GetCTR();
|
||||
|
||||
@@ -71,6 +71,13 @@ bool TranslatorVisitor::DMB(Imm<4> /*CRm*/) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::ISB(Imm<4> /*CRm*/) {
|
||||
ir.InstructionSynchronizationBarrier();
|
||||
ir.SetPC(ir.Imm64(ir.current_location->PC() + 4));
|
||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::MSR_reg(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt) {
|
||||
const auto sys_reg = concatenate(Imm<1>{1}, o0, op1, CRn, CRm, op2).ZeroExtend<SystemRegisterEncoding>();
|
||||
switch (sys_reg) {
|
||||
|
||||
@@ -395,19 +395,20 @@ bool Inst::IsCoprocessorInstruction() const {
|
||||
}
|
||||
|
||||
bool Inst::MayHaveSideEffects() const {
|
||||
return op == Opcode::PushRSB ||
|
||||
op == Opcode::A64SetCheckBit ||
|
||||
op == Opcode::A64DataCacheOperationRaised ||
|
||||
op == Opcode::A64DataSynchronizationBarrier ||
|
||||
op == Opcode::A64DataMemoryBarrier ||
|
||||
CausesCPUException() ||
|
||||
WritesToCoreRegister() ||
|
||||
WritesToSystemRegister() ||
|
||||
WritesToCPSR() ||
|
||||
WritesToFPCR() ||
|
||||
WritesToFPSR() ||
|
||||
AltersExclusiveState() ||
|
||||
IsMemoryWrite() ||
|
||||
return op == Opcode::PushRSB ||
|
||||
op == Opcode::A64SetCheckBit ||
|
||||
op == Opcode::A64DataCacheOperationRaised ||
|
||||
op == Opcode::A64DataSynchronizationBarrier ||
|
||||
op == Opcode::A64DataMemoryBarrier ||
|
||||
op == Opcode::A64InstructionSynchronizationBarrier ||
|
||||
CausesCPUException() ||
|
||||
WritesToCoreRegister() ||
|
||||
WritesToSystemRegister() ||
|
||||
WritesToCPSR() ||
|
||||
WritesToFPCR() ||
|
||||
WritesToFPSR() ||
|
||||
AltersExclusiveState() ||
|
||||
IsMemoryWrite() ||
|
||||
IsCoprocessorInstruction();
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ A64OPC(ExceptionRaised, T::Void, T::U64,
|
||||
A64OPC(DataCacheOperationRaised, T::Void, T::U64, T::U64 )
|
||||
A64OPC(DataSynchronizationBarrier, T::Void, )
|
||||
A64OPC(DataMemoryBarrier, T::Void, )
|
||||
A64OPC(InstructionSynchronizationBarrier, T::Void, )
|
||||
A64OPC(GetCNTFRQ, T::U32, )
|
||||
A64OPC(GetCNTPCT, T::U64, )
|
||||
A64OPC(GetCTR, T::U32, )
|
||||
|
||||
Reference in New Issue
Block a user