From bfd65bedfe41b4e4b020cb62d66f748fc42e2054 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sun, 11 Feb 2018 23:27:28 +0000 Subject: [PATCH] A64: Implement DSB, DMB --- src/backend_x64/a64_emit_x64.cpp | 8 ++++++++ src/frontend/A64/decoder/a64.inc | 4 ++-- src/frontend/A64/ir_emitter.cpp | 8 ++++++++ src/frontend/A64/ir_emitter.h | 2 ++ src/frontend/A64/translate/impl/system.cpp | 10 ++++++++++ src/frontend/ir/microinstruction.cpp | 2 ++ src/frontend/ir/opcodes.inc | 2 ++ 7 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/backend_x64/a64_emit_x64.cpp b/src/backend_x64/a64_emit_x64.cpp index 4e5e9c2a..98e6b56f 100644 --- a/src/backend_x64/a64_emit_x64.cpp +++ b/src/backend_x64/a64_emit_x64.cpp @@ -316,6 +316,14 @@ void A64EmitX64::EmitA64DataCacheOperationRaised(A64EmitContext& ctx, IR::Inst* DEVIRT(conf.callbacks, &A64::UserCallbacks::DataCacheOperationRaised).EmitCall(code); } +void A64EmitX64::EmitA64DataSynchronizationBarrier(A64EmitContext&, IR::Inst*) { + code.mfence(); +} + +void A64EmitX64::EmitA64DataMemoryBarrier(A64EmitContext&, IR::Inst*) { + code.lfence(); +} + void A64EmitX64::EmitA64ReadMemory8(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(inst, {}, args[0]); diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index bcce0cd3..e1c26acf 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -62,8 +62,8 @@ INST(SEVL, "SEVL", "11010 //INST(ESB, "ESB", "11010101000000110010001000011111") //INST(PSB, "PSB CSYNC", "11010101000000110010001000111111") //INST(CLREX, "CLREX", "11010101000000110011MMMM01011111") -//INST(DSB, "DSB", "11010101000000110011MMMM10011111") -//INST(DMB, "DMB", "11010101000000110011MMMM10111111") +INST(DSB, "DSB", "11010101000000110011MMMM10011111") +INST(DMB, "DMB", "11010101000000110011MMMM10111111") //INST(ISB, "ISB", "11010101000000110011MMMM11011111") //INST(SYS, "SYS", "1101010100001oooNNNNMMMMooottttt") //INST(MSR_reg, "MSR (register)", "110101010001poooNNNNMMMMooottttt") diff --git a/src/frontend/A64/ir_emitter.cpp b/src/frontend/A64/ir_emitter.cpp index 366325a3..b717709c 100644 --- a/src/frontend/A64/ir_emitter.cpp +++ b/src/frontend/A64/ir_emitter.cpp @@ -45,6 +45,14 @@ void IREmitter::DataCacheOperationRaised(DataCacheOperation op, const IR::U64& v Inst(Opcode::A64DataCacheOperationRaised, Imm64(static_cast(op)), value); } +void IREmitter::DataSynchronizationBarrier() { + Inst(Opcode::A64DataSynchronizationBarrier); +} + +void IREmitter::DataMemoryBarrier() { + Inst(Opcode::A64DataMemoryBarrier); +} + IR::U8 IREmitter::ReadMemory8(const IR::U64& vaddr) { return Inst(Opcode::A64ReadMemory8, vaddr); } diff --git a/src/frontend/A64/ir_emitter.h b/src/frontend/A64/ir_emitter.h index 7a7a05f5..1c0c3686 100644 --- a/src/frontend/A64/ir_emitter.h +++ b/src/frontend/A64/ir_emitter.h @@ -42,6 +42,8 @@ public: void CallSupervisor(u32 imm); void ExceptionRaised(Exception exception); void DataCacheOperationRaised(DataCacheOperation op, const IR::U64& value); + void DataSynchronizationBarrier(); + void DataMemoryBarrier(); IR::U8 ReadMemory8(const IR::U64& vaddr); IR::U16 ReadMemory16(const IR::U64& vaddr); diff --git a/src/frontend/A64/translate/impl/system.cpp b/src/frontend/A64/translate/impl/system.cpp index 004085e2..074cc74a 100644 --- a/src/frontend/A64/translate/impl/system.cpp +++ b/src/frontend/A64/translate/impl/system.cpp @@ -36,4 +36,14 @@ bool TranslatorVisitor::SEVL() { return true; } +bool TranslatorVisitor::DSB(Imm<4> /*CRm*/) { + ir.DataSynchronizationBarrier(); + return true; +} + +bool TranslatorVisitor::DMB(Imm<4> /*CRm*/) { + ir.DataMemoryBarrier(); + return true; +} + } // namespace Dynarmic::A64 diff --git a/src/frontend/ir/microinstruction.cpp b/src/frontend/ir/microinstruction.cpp index bc34993f..dcdf2b68 100644 --- a/src/frontend/ir/microinstruction.cpp +++ b/src/frontend/ir/microinstruction.cpp @@ -272,6 +272,8 @@ bool Inst::MayHaveSideEffects() const { return op == Opcode::PushRSB || op == Opcode::A64SetCheckBit || op == Opcode::A64DataCacheOperationRaised || + op == Opcode::A64DataSynchronizationBarrier || + op == Opcode::A64DataMemoryBarrier || CausesCPUException() || WritesToCoreRegister() || WritesToCPSR() || diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index bef7e6ac..05cb2469 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -59,6 +59,8 @@ A64OPC(SetPC, T::Void, T::U64 A64OPC(CallSupervisor, T::Void, T::U32 ) A64OPC(ExceptionRaised, T::Void, T::U64, T::U64 ) A64OPC(DataCacheOperationRaised, T::Void, T::U64, T::U64 ) +A64OPC(DataSynchronizationBarrier, T::Void, ) +A64OPC(DataMemoryBarrier, T::Void, ) // Hints OPCODE(PushRSB, T::Void, T::U64 )