diff --git a/ARMeilleure/CodeGen/X86/Assembler.cs b/ARMeilleure/CodeGen/X86/Assembler.cs index ed33525295..c15deadc53 100644 --- a/ARMeilleure/CodeGen/X86/Assembler.cs +++ b/ARMeilleure/CodeGen/X86/Assembler.cs @@ -358,6 +358,12 @@ namespace ARMeilleure.CodeGen.X86 WriteInstruction(dest, source, type, X86Instruction.Lea); } + public void LockOr(Operand dest, Operand source, OperandType type) + { + WriteByte(LockPrefix); + WriteInstruction(dest, source, type, X86Instruction.Or); + } + public void Mov(Operand dest, Operand source, OperandType type) { WriteInstruction(dest, source, type, X86Instruction.Mov); diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs index 72d0e5d82f..8d8d3b0a23 100644 --- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs +++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs @@ -49,6 +49,7 @@ namespace ARMeilleure.CodeGen.X86 Add(Instruction.Load, GenerateLoad); Add(Instruction.Load16, GenerateLoad16); Add(Instruction.Load8, GenerateLoad8); + Add(Instruction.MemoryBarrier, GenerateMemoryBarrier); Add(Instruction.Multiply, GenerateMultiply); Add(Instruction.Multiply64HighSI, GenerateMultiply64HighSI); Add(Instruction.Multiply64HighUI, GenerateMultiply64HighUI); @@ -538,7 +539,7 @@ namespace ARMeilleure.CodeGen.X86 context.Assembler.Lea(dest, memOp, dest.Type); } } - else + else { ValidateBinOp(dest, src1, src2); @@ -976,6 +977,11 @@ namespace ARMeilleure.CodeGen.X86 context.Assembler.Movzx8(value, address, value.Type); } + private static void GenerateMemoryBarrier(CodeGenContext context, Operation operation) + { + context.Assembler.LockOr(MemoryOp(OperandType.I64, Register(X86Register.Rsp)), Const(0), OperandType.I32); + } + private static void GenerateMultiply(CodeGenContext context, Operation operation) { Operand dest = operation.Destination; diff --git a/ARMeilleure/Instructions/InstEmitMemoryEx.cs b/ARMeilleure/Instructions/InstEmitMemoryEx.cs index 522b2a4708..88b9d2f0c4 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryEx.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryEx.cs @@ -167,9 +167,7 @@ namespace ARMeilleure.Instructions private static void EmitBarrier(ArmEmitterContext context) { - // Note: This barrier is most likely not necessary, and probably - // doesn't make any difference since we need to do a ton of stuff - // (software MMU emulation) to read or write anything anyway. + context.MemoryBarrier(); } } } \ No newline at end of file diff --git a/ARMeilleure/IntermediateRepresentation/Instruction.cs b/ARMeilleure/IntermediateRepresentation/Instruction.cs index b675ed1cc5..b55fe1dace 100644 --- a/ARMeilleure/IntermediateRepresentation/Instruction.cs +++ b/ARMeilleure/IntermediateRepresentation/Instruction.cs @@ -26,6 +26,7 @@ namespace ARMeilleure.IntermediateRepresentation Load16, Load8, LoadArgument, + MemoryBarrier, Multiply, Multiply64HighSI, Multiply64HighUI, diff --git a/ARMeilleure/Translation/EmitterContext.cs b/ARMeilleure/Translation/EmitterContext.cs index 7525a5d4e4..8fcb4deec8 100644 --- a/ARMeilleure/Translation/EmitterContext.cs +++ b/ARMeilleure/Translation/EmitterContext.cs @@ -325,6 +325,11 @@ namespace ARMeilleure.Translation Add(Instruction.LoadFromContext); } + public void MemoryBarrier() + { + Add(Instruction.MemoryBarrier); + } + public Operand Multiply(Operand op1, Operand op2) { return Add(Instruction.Multiply, Local(op1.Type), op1, op2); diff --git a/ARMeilleure/Translation/PTC/Ptc.cs b/ARMeilleure/Translation/PTC/Ptc.cs index 2142e34f52..4cf01a76a6 100644 --- a/ARMeilleure/Translation/PTC/Ptc.cs +++ b/ARMeilleure/Translation/PTC/Ptc.cs @@ -27,7 +27,7 @@ namespace ARMeilleure.Translation.PTC private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0"; - private const uint InternalVersion = 2953; //! To be incremented manually for each change to the ARMeilleure project. + private const uint InternalVersion = 3015; //! To be incremented manually for each change to the ARMeilleure project. private const string ActualDir = "0"; private const string BackupDir = "1";