Adding CONTEXT_BARRIER to force the PPC context to synchronize.

This is just an annotation right now, as it's not actually needed.
This commit is contained in:
Ben Vanik 2015-11-25 14:48:36 -08:00
parent 54215d9fb4
commit dfd92757a9
7 changed files with 34 additions and 4 deletions

View File

@ -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_I32, STORE_CONTEXT_I64, STORE_CONTEXT_F32,
STORE_CONTEXT_F64, STORE_CONTEXT_V128); STORE_CONTEXT_F64, STORE_CONTEXT_V128);
// ============================================================================
// OPCODE_CONTEXT_BARRIER
// ============================================================================
struct CONTEXT_BARRIER
: Sequence<CONTEXT_BARRIER, I<OPCODE_CONTEXT_BARRIER, VoidOp>> {
static void Emit(X64Emitter& e, const EmitArgType& i) {}
};
EMITTER_OPCODE_TABLE(OPCODE_CONTEXT_BARRIER, CONTEXT_BARRIER);
// ============================================================================ // ============================================================================
// OPCODE_LOAD_MMIO // OPCODE_LOAD_MMIO
// ============================================================================ // ============================================================================
@ -7112,6 +7121,7 @@ void RegisterSequences() {
Register_OPCODE_STORE_LOCAL(); Register_OPCODE_STORE_LOCAL();
Register_OPCODE_LOAD_CONTEXT(); Register_OPCODE_LOAD_CONTEXT();
Register_OPCODE_STORE_CONTEXT(); Register_OPCODE_STORE_CONTEXT();
Register_OPCODE_CONTEXT_BARRIER();
Register_OPCODE_LOAD_MMIO(); Register_OPCODE_LOAD_MMIO();
Register_OPCODE_STORE_MMIO(); Register_OPCODE_STORE_MMIO();
Register_OPCODE_LOAD(); Register_OPCODE_LOAD();

View File

@ -123,6 +123,13 @@ bool PPCHIRBuilder::Emit(GuestFunction* function, uint32_t flags) {
// Stash instruction offset. It's either the SOURCE_OFFSET or the COMMENT. // Stash instruction offset. It's either the SOURCE_OFFSET or the COMMENT.
instr_offset_list_[offset] = first_instr; 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) { if (!i.type) {
XELOGE("Invalid instruction %.8llX %.8X", i.address, i.code); XELOGE("Invalid instruction %.8llX %.8X", i.address, i.code);
Comment("INVALID!"); Comment("INVALID!");

View File

@ -74,10 +74,11 @@ enum xe_ppc_instr_mask_e : uint32_t {
typedef enum { typedef enum {
kXEPPCInstrTypeGeneral = (1 << 0), kXEPPCInstrTypeGeneral = (1 << 0),
kXEPPCInstrTypeBranch = (1 << 1), kXEPPCInstrTypeSynchronizeContext = (1 << 1),
kXEPPCInstrTypeBranchCond = kXEPPCInstrTypeBranch | (1 << 2), kXEPPCInstrTypeBranch = kXEPPCInstrTypeSynchronizeContext | (1 << 2),
kXEPPCInstrTypeBranchAlways = kXEPPCInstrTypeBranch | (1 << 3), kXEPPCInstrTypeBranchCond = kXEPPCInstrTypeBranch | (1 << 3),
kXEPPCInstrTypeSyscall = (1 << 4), kXEPPCInstrTypeBranchAlways = kXEPPCInstrTypeBranch | (1 << 4),
kXEPPCInstrTypeSyscall = kXEPPCInstrTypeSynchronizeContext | (1 << 5),
} xe_ppc_instr_type_e; } xe_ppc_instr_type_e;
typedef enum { typedef enum {

View File

@ -1211,6 +1211,10 @@ void HIRBuilder::StoreContext(size_t offset, Value* value) {
i->src3.value = NULL; i->src3.value = NULL;
} }
void HIRBuilder::ContextBarrier() {
AppendInstr(OPCODE_CONTEXT_BARRIER_info, 0);
}
Value* HIRBuilder::LoadMmio(cpu::MMIORange* mmio_range, uint32_t address, Value* HIRBuilder::LoadMmio(cpu::MMIORange* mmio_range, uint32_t address,
TypeName type) { TypeName type) {
Instr* i = AppendInstr(OPCODE_LOAD_MMIO_info, 0, AllocValue(type)); Instr* i = AppendInstr(OPCODE_LOAD_MMIO_info, 0, AllocValue(type));

View File

@ -142,6 +142,7 @@ class HIRBuilder {
Value* LoadContext(size_t offset, TypeName type); Value* LoadContext(size_t offset, TypeName type);
void StoreContext(size_t offset, Value* value); void StoreContext(size_t offset, Value* value);
void ContextBarrier();
Value* LoadMmio(cpu::MMIORange* mmio_range, uint32_t address, TypeName type); Value* LoadMmio(cpu::MMIORange* mmio_range, uint32_t address, TypeName type);
void StoreMmio(cpu::MMIORange* mmio_range, uint32_t address, Value* value); void StoreMmio(cpu::MMIORange* mmio_range, uint32_t address, Value* value);

View File

@ -148,6 +148,7 @@ enum Opcode {
OPCODE_STORE_LOCAL, OPCODE_STORE_LOCAL,
OPCODE_LOAD_CONTEXT, OPCODE_LOAD_CONTEXT,
OPCODE_STORE_CONTEXT, OPCODE_STORE_CONTEXT,
OPCODE_CONTEXT_BARRIER,
OPCODE_LOAD_MMIO, OPCODE_LOAD_MMIO,
OPCODE_STORE_MMIO, OPCODE_STORE_MMIO,
OPCODE_LOAD, OPCODE_LOAD,

View File

@ -213,6 +213,12 @@ DEFINE_OPCODE(
OPCODE_SIG_X_O_V, OPCODE_SIG_X_O_V,
0) 0)
DEFINE_OPCODE(
OPCODE_CONTEXT_BARRIER,
"context_barrier",
OPCODE_SIG_X,
0)
DEFINE_OPCODE( DEFINE_OPCODE(
OPCODE_LOAD_MMIO, OPCODE_LOAD_MMIO,
"load_mmio", "load_mmio",