aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure')
-rw-r--r--ARMeilleure/Instructions/InstEmitMemoryHelper.cs23
-rw-r--r--ARMeilleure/Instructions/NativeInterface.cs14
-rw-r--r--ARMeilleure/Memory/IMemoryManager.cs3
-rw-r--r--ARMeilleure/Translation/Delegates.cs2
-rw-r--r--ARMeilleure/Translation/PTC/Ptc.cs2
5 files changed, 22 insertions, 22 deletions
diff --git a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs
index 390d167d..fd5c5bca 100644
--- a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs
+++ b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs
@@ -391,23 +391,22 @@ namespace ARMeilleure.Instructions
if (lblSlowPath != null)
{
- context.BranchIf(lblSlowPath, pte, Const(0L), Comparison.LessOrEqual);
+ ulong protection = (write ? 3UL : 1UL) << 48;
+ context.BranchIfTrue(lblSlowPath, context.BitwiseAnd(pte, Const(protection)));
}
else
{
// When no label is provided to jump to a slow path if the address is invalid,
// we do the validation ourselves, and throw if needed.
- if (write)
- {
- Operand lblNotWatched = Label();
- // Is the page currently being monitored for modifications? If so we need to call MarkRegionAsModified.
- context.BranchIf(lblNotWatched, pte, Const(0L), Comparison.GreaterOrEqual, BasicBlockFrequency.Cold);
+ Operand lblNotWatched = Label();
- // Mark the region as modified. Size here doesn't matter as address is assumed to be size aligned here.
- context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.MarkRegionAsModified)), address, Const(1UL));
- context.MarkLabel(lblNotWatched);
- }
+ // Is the page currently being tracked for read/write? If so we need to call MarkRegionAsModified.
+ context.BranchIf(lblNotWatched, pte, Const(0L), Comparison.GreaterOrEqual, BasicBlockFrequency.Cold);
+
+ // Mark the region as modified. Size here doesn't matter as address is assumed to be size aligned here.
+ context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)), address, Const(1UL), Const(write ? 1 : 0));
+ context.MarkLabel(lblNotWatched);
Operand lblNonNull = Label();
@@ -417,10 +416,10 @@ namespace ARMeilleure.Instructions
// The call is not expected to return (it should throw).
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)), address);
context.MarkLabel(lblNonNull);
-
- pte = context.BitwiseAnd(pte, Const(0xffffffffffffUL));
}
+ pte = context.BitwiseAnd(pte, Const(0xffffffffffffUL)); // Ignore any software protection bits. (they are still used by c# memory access)
+
Operand pageOffset = context.BitwiseAnd(address, Const(address.Type, PageMask));
if (pageOffset.Type == OperandType.I32)
diff --git a/ARMeilleure/Instructions/NativeInterface.cs b/ARMeilleure/Instructions/NativeInterface.cs
index b4afcc02..8fb98df8 100644
--- a/ARMeilleure/Instructions/NativeInterface.cs
+++ b/ARMeilleure/Instructions/NativeInterface.cs
@@ -163,27 +163,27 @@ namespace ARMeilleure.Instructions
#region "Read"
public static byte ReadByte(ulong address)
{
- return GetMemoryManager().Read<byte>(address);
+ return GetMemoryManager().ReadTracked<byte>(address);
}
public static ushort ReadUInt16(ulong address)
{
- return GetMemoryManager().Read<ushort>(address);
+ return GetMemoryManager().ReadTracked<ushort>(address);
}
public static uint ReadUInt32(ulong address)
{
- return GetMemoryManager().Read<uint>(address);
+ return GetMemoryManager().ReadTracked<uint>(address);
}
public static ulong ReadUInt64(ulong address)
{
- return GetMemoryManager().Read<ulong>(address);
+ return GetMemoryManager().ReadTracked<ulong>(address);
}
public static V128 ReadVector128(ulong address)
{
- return GetMemoryManager().Read<V128>(address);
+ return GetMemoryManager().ReadTracked<V128>(address);
}
#endregion
@@ -214,9 +214,9 @@ namespace ARMeilleure.Instructions
}
#endregion
- public static void MarkRegionAsModified(ulong address, ulong size)
+ public static void SignalMemoryTracking(ulong address, ulong size, bool write)
{
- GetMemoryManager().MarkRegionAsModified(address, size);
+ GetMemoryManager().SignalMemoryTracking(address, size, write);
}
public static void ThrowInvalidMemoryAccess(ulong address)
diff --git a/ARMeilleure/Memory/IMemoryManager.cs b/ARMeilleure/Memory/IMemoryManager.cs
index f4e26886..33153903 100644
--- a/ARMeilleure/Memory/IMemoryManager.cs
+++ b/ARMeilleure/Memory/IMemoryManager.cs
@@ -9,12 +9,13 @@ namespace ARMeilleure.Memory
IntPtr PageTablePointer { get; }
T Read<T>(ulong va) where T : unmanaged;
+ T ReadTracked<T>(ulong va) where T : unmanaged;
void Write<T>(ulong va, T value) where T : unmanaged;
ref T GetRef<T>(ulong va) where T : unmanaged;
bool IsMapped(ulong va);
- void MarkRegionAsModified(ulong va, ulong size);
+ void SignalMemoryTracking(ulong va, ulong size, bool write);
}
} \ No newline at end of file
diff --git a/ARMeilleure/Translation/Delegates.cs b/ARMeilleure/Translation/Delegates.cs
index 88d01818..c64dc8f0 100644
--- a/ARMeilleure/Translation/Delegates.cs
+++ b/ARMeilleure/Translation/Delegates.cs
@@ -117,7 +117,6 @@ namespace ARMeilleure.Translation
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidr32))); // A32 only.
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl0)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl032))); // A32 only.
- SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.MarkRegionAsModified)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)));
@@ -129,6 +128,7 @@ namespace ARMeilleure.Translation
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); // A32 only.
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032))); // A32 only.
+ SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)));
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Undefined)));
diff --git a/ARMeilleure/Translation/PTC/Ptc.cs b/ARMeilleure/Translation/PTC/Ptc.cs
index bf5fd838..dd1c44b2 100644
--- a/ARMeilleure/Translation/PTC/Ptc.cs
+++ b/ARMeilleure/Translation/PTC/Ptc.cs
@@ -21,7 +21,7 @@ namespace ARMeilleure.Translation.PTC
{
private const string HeaderMagic = "PTChd";
- private const int InternalVersion = 1577; //! To be incremented manually for each change to the ARMeilleure project.
+ private const int InternalVersion = 1273; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0";
private const string BackupDir = "1";