Просмотр исходного кода

Add host CPU memory barriers for DMB/DSB and ordered load/store (#3015)

* Add host CPU memory barriers for DMB/DSB and ordered load/store

* PPTC version bump

* Revert to old barrier order
gdkchan 4 лет назад
Родитель
Сommit
f0824fde9f

+ 6 - 0
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);

+ 7 - 1
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;

+ 1 - 3
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();
         }
     }
 }

+ 1 - 0
ARMeilleure/IntermediateRepresentation/Instruction.cs

@@ -26,6 +26,7 @@ namespace ARMeilleure.IntermediateRepresentation
         Load16,
         Load8,
         LoadArgument,
+        MemoryBarrier,
         Multiply,
         Multiply64HighSI,
         Multiply64HighUI,

+ 5 - 0
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);

+ 1 - 1
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";