Implement inline memory load/store exclusive and ordered (#1413)
* Implement inline memory load/store exclusive * Fix missing REX prefix on 8-bits CMPXCHG * Increment PTC version due to bugfix * Remove redundant memory checks * Address PR feedback * Increment PPTC version
This commit is contained in:
parent
57bb0abda3
commit
9878fc2d3c
19 changed files with 385 additions and 376 deletions
|
@ -12,8 +12,9 @@ namespace ARMeilleure.Memory
|
|||
void Write<T>(ulong va, T value) where T : unmanaged;
|
||||
|
||||
ref T GetRef<T>(ulong va) where T : unmanaged;
|
||||
ref T GetRefNoChecks<T>(ulong va) where T : unmanaged;
|
||||
|
||||
bool IsMapped(ulong va);
|
||||
|
||||
void MarkRegionAsModified(ulong va, ulong size);
|
||||
}
|
||||
}
|
23
ARMeilleure/Memory/InvalidAccessException.cs
Normal file
23
ARMeilleure/Memory/InvalidAccessException.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
|
||||
namespace ARMeilleure.Memory
|
||||
{
|
||||
class InvalidAccessException : Exception
|
||||
{
|
||||
public InvalidAccessException()
|
||||
{
|
||||
}
|
||||
|
||||
public InvalidAccessException(ulong address) : base($"Invalid memory access at virtual address 0x{address:X16}.")
|
||||
{
|
||||
}
|
||||
|
||||
public InvalidAccessException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public InvalidAccessException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
|
||||
namespace ARMeilleure.Memory
|
||||
{
|
||||
static class MemoryManagerPal
|
||||
{
|
||||
private delegate V128 CompareExchange128(ref V128 location, V128 expected, V128 desired);
|
||||
|
||||
private static CompareExchange128 _compareExchange128;
|
||||
|
||||
private static object _lock;
|
||||
|
||||
static MemoryManagerPal()
|
||||
{
|
||||
_lock = new object();
|
||||
}
|
||||
|
||||
public static V128 AtomicLoad128(ref V128 location)
|
||||
{
|
||||
return GetCompareAndSwap128()(ref location, V128.Zero, V128.Zero);
|
||||
}
|
||||
|
||||
public static V128 CompareAndSwap128(ref V128 location, V128 expected, V128 desired)
|
||||
{
|
||||
return GetCompareAndSwap128()(ref location, 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.CompareAndSwap(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue