aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Memory/MemoryManagerPal.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Memory/MemoryManagerPal.cs')
-rw-r--r--ARMeilleure/Memory/MemoryManagerPal.cs77
1 files changed, 77 insertions, 0 deletions
diff --git a/ARMeilleure/Memory/MemoryManagerPal.cs b/ARMeilleure/Memory/MemoryManagerPal.cs
new file mode 100644
index 00000000..64191a0a
--- /dev/null
+++ b/ARMeilleure/Memory/MemoryManagerPal.cs
@@ -0,0 +1,77 @@
+using ARMeilleure.IntermediateRepresentation;
+using ARMeilleure.State;
+using ARMeilleure.Translation;
+using System;
+
+namespace ARMeilleure.Memory
+{
+ static class MemoryManagerPal
+ {
+ private delegate V128 CompareExchange128(IntPtr address, V128 expected, V128 desired);
+
+ private static CompareExchange128 _compareExchange128;
+
+ private static object _lock;
+
+ static MemoryManagerPal()
+ {
+ _lock = new object();
+ }
+
+ public static V128 AtomicLoad128(IntPtr address)
+ {
+ return GetCompareAndSwap128()(address, V128.Zero, V128.Zero);
+ }
+
+ public static V128 CompareAndSwap128(IntPtr address, V128 expected, V128 desired)
+ {
+ return GetCompareAndSwap128()(address, expected, desired);
+ }
+
+ private static CompareExchange128 GetCompareAndSwap128()
+ {
+ if (_compareExchange128 == null)
+ {
+ GenerateCompareAndSwap128();
+ }
+
+ return _compareExchange128;
+ }
+
+ private static void GenerateCompareAndSwap128()
+ {
+ lock (_lock)
+ {
+ if (_compareExchange128 != null)
+ {
+ return;
+ }
+
+ EmitterContext context = new EmitterContext();
+
+ Operand address = context.LoadArgument(OperandType.I64, 0);
+ Operand expected = context.LoadArgument(OperandType.V128, 1);
+ Operand desired = context.LoadArgument(OperandType.V128, 2);
+
+ Operand result = context.CompareAndSwap128(address, expected, desired);
+
+ context.Return(result);
+
+ ControlFlowGraph cfg = context.GetControlFlowGraph();
+
+ OperandType[] argTypes = new OperandType[]
+ {
+ OperandType.I64,
+ OperandType.V128,
+ OperandType.V128
+ };
+
+ _compareExchange128 = Compiler.Compile<CompareExchange128>(
+ cfg,
+ argTypes,
+ OperandType.V128,
+ CompilerOptions.HighCq);
+ }
+ }
+ }
+} \ No newline at end of file