From dfd92757a9b8f278b1ae7437f524f5f859c9a40c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 25 Nov 2015 14:48:36 -0800 Subject: [PATCH] Adding CONTEXT_BARRIER to force the PPC context to synchronize. This is just an annotation right now, as it's not actually needed. --- src/xenia/cpu/backend/x64/x64_sequences.cc | 10 ++++++++++ src/xenia/cpu/frontend/ppc_hir_builder.cc | 7 +++++++ src/xenia/cpu/frontend/ppc_instr.h | 9 +++++---- src/xenia/cpu/hir/hir_builder.cc | 4 ++++ src/xenia/cpu/hir/hir_builder.h | 1 + src/xenia/cpu/hir/opcodes.h | 1 + src/xenia/cpu/hir/opcodes.inl | 6 ++++++ 7 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/xenia/cpu/backend/x64/x64_sequences.cc b/src/xenia/cpu/backend/x64/x64_sequences.cc index c3c2babbb..2aa290952 100644 --- a/src/xenia/cpu/backend/x64/x64_sequences.cc +++ b/src/xenia/cpu/backend/x64/x64_sequences.cc @@ -2007,6 +2007,15 @@ EMITTER_OPCODE_TABLE(OPCODE_STORE_CONTEXT, STORE_CONTEXT_I8, STORE_CONTEXT_I16, STORE_CONTEXT_I32, STORE_CONTEXT_I64, STORE_CONTEXT_F32, STORE_CONTEXT_F64, STORE_CONTEXT_V128); +// ============================================================================ +// OPCODE_CONTEXT_BARRIER +// ============================================================================ +struct CONTEXT_BARRIER + : Sequence> { + static void Emit(X64Emitter& e, const EmitArgType& i) {} +}; +EMITTER_OPCODE_TABLE(OPCODE_CONTEXT_BARRIER, CONTEXT_BARRIER); + // ============================================================================ // OPCODE_LOAD_MMIO // ============================================================================ @@ -7112,6 +7121,7 @@ void RegisterSequences() { Register_OPCODE_STORE_LOCAL(); Register_OPCODE_LOAD_CONTEXT(); Register_OPCODE_STORE_CONTEXT(); + Register_OPCODE_CONTEXT_BARRIER(); Register_OPCODE_LOAD_MMIO(); Register_OPCODE_STORE_MMIO(); Register_OPCODE_LOAD(); diff --git a/src/xenia/cpu/frontend/ppc_hir_builder.cc b/src/xenia/cpu/frontend/ppc_hir_builder.cc index 9c2998d9d..b822baade 100644 --- a/src/xenia/cpu/frontend/ppc_hir_builder.cc +++ b/src/xenia/cpu/frontend/ppc_hir_builder.cc @@ -123,6 +123,13 @@ bool PPCHIRBuilder::Emit(GuestFunction* function, uint32_t flags) { // Stash instruction offset. It's either the SOURCE_OFFSET or the COMMENT. instr_offset_list_[offset] = first_instr; + // Synchronize the PPC context as required. + // This will ensure all registers are saved to the PPC context before this + // instruction executes. + if (i.type->type & kXEPPCInstrTypeSynchronizeContext) { + ContextBarrier(); + } + if (!i.type) { XELOGE("Invalid instruction %.8llX %.8X", i.address, i.code); Comment("INVALID!"); diff --git a/src/xenia/cpu/frontend/ppc_instr.h b/src/xenia/cpu/frontend/ppc_instr.h index 99a61a4b2..a1b8fc96d 100644 --- a/src/xenia/cpu/frontend/ppc_instr.h +++ b/src/xenia/cpu/frontend/ppc_instr.h @@ -74,10 +74,11 @@ enum xe_ppc_instr_mask_e : uint32_t { typedef enum { kXEPPCInstrTypeGeneral = (1 << 0), - kXEPPCInstrTypeBranch = (1 << 1), - kXEPPCInstrTypeBranchCond = kXEPPCInstrTypeBranch | (1 << 2), - kXEPPCInstrTypeBranchAlways = kXEPPCInstrTypeBranch | (1 << 3), - kXEPPCInstrTypeSyscall = (1 << 4), + kXEPPCInstrTypeSynchronizeContext = (1 << 1), + kXEPPCInstrTypeBranch = kXEPPCInstrTypeSynchronizeContext | (1 << 2), + kXEPPCInstrTypeBranchCond = kXEPPCInstrTypeBranch | (1 << 3), + kXEPPCInstrTypeBranchAlways = kXEPPCInstrTypeBranch | (1 << 4), + kXEPPCInstrTypeSyscall = kXEPPCInstrTypeSynchronizeContext | (1 << 5), } xe_ppc_instr_type_e; typedef enum { diff --git a/src/xenia/cpu/hir/hir_builder.cc b/src/xenia/cpu/hir/hir_builder.cc index ab9468cb1..a27f0b86a 100644 --- a/src/xenia/cpu/hir/hir_builder.cc +++ b/src/xenia/cpu/hir/hir_builder.cc @@ -1211,6 +1211,10 @@ void HIRBuilder::StoreContext(size_t offset, Value* value) { i->src3.value = NULL; } +void HIRBuilder::ContextBarrier() { + AppendInstr(OPCODE_CONTEXT_BARRIER_info, 0); +} + Value* HIRBuilder::LoadMmio(cpu::MMIORange* mmio_range, uint32_t address, TypeName type) { Instr* i = AppendInstr(OPCODE_LOAD_MMIO_info, 0, AllocValue(type)); diff --git a/src/xenia/cpu/hir/hir_builder.h b/src/xenia/cpu/hir/hir_builder.h index 59090f668..d6e0e8ccc 100644 --- a/src/xenia/cpu/hir/hir_builder.h +++ b/src/xenia/cpu/hir/hir_builder.h @@ -142,6 +142,7 @@ class HIRBuilder { Value* LoadContext(size_t offset, TypeName type); void StoreContext(size_t offset, Value* value); + void ContextBarrier(); Value* LoadMmio(cpu::MMIORange* mmio_range, uint32_t address, TypeName type); void StoreMmio(cpu::MMIORange* mmio_range, uint32_t address, Value* value); diff --git a/src/xenia/cpu/hir/opcodes.h b/src/xenia/cpu/hir/opcodes.h index 0fd952cbe..84bf2b320 100644 --- a/src/xenia/cpu/hir/opcodes.h +++ b/src/xenia/cpu/hir/opcodes.h @@ -148,6 +148,7 @@ enum Opcode { OPCODE_STORE_LOCAL, OPCODE_LOAD_CONTEXT, OPCODE_STORE_CONTEXT, + OPCODE_CONTEXT_BARRIER, OPCODE_LOAD_MMIO, OPCODE_STORE_MMIO, OPCODE_LOAD, diff --git a/src/xenia/cpu/hir/opcodes.inl b/src/xenia/cpu/hir/opcodes.inl index c7c8b6f67..c5deb7ff8 100644 --- a/src/xenia/cpu/hir/opcodes.inl +++ b/src/xenia/cpu/hir/opcodes.inl @@ -213,6 +213,12 @@ DEFINE_OPCODE( OPCODE_SIG_X_O_V, 0) +DEFINE_OPCODE( + OPCODE_CONTEXT_BARRIER, + "context_barrier", + OPCODE_SIG_X, + 0) + DEFINE_OPCODE( OPCODE_LOAD_MMIO, "load_mmio",