Optimize address translation and write tracking on the MMU (#571)
* Implement faster address translation and write tracking on the MMU * Rename MemoryAlloc to MemoryManagement, and other nits * Support multi-level page tables * Fix typo * Reword comment a bit * Support scalar vector loads/stores on the memory fast path, and minor fixes * Add missing cast * Alignment * Fix VirtualFree function signature * Change MemoryProtection enum to uint aswell for consistency
This commit is contained in:
parent
a3d46e4133
commit
5001f78b1d
24 changed files with 1005 additions and 621 deletions
|
@ -1,5 +1,6 @@
|
|||
using ChocolArm64.Decoders;
|
||||
using ChocolArm64.Instructions;
|
||||
using ChocolArm64.Memory;
|
||||
using ChocolArm64.State;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -10,6 +11,8 @@ namespace ChocolArm64.Translation
|
|||
{
|
||||
class ILEmitterCtx
|
||||
{
|
||||
public MemoryManager Memory { get; }
|
||||
|
||||
private TranslatorCache _cache;
|
||||
private TranslatorQueue _queue;
|
||||
|
||||
|
@ -43,19 +46,34 @@ namespace ChocolArm64.Translation
|
|||
//values needed by some functions, since IL doesn't have a swap instruction.
|
||||
//You can use any value here as long it doesn't conflict with the indices
|
||||
//for the other registers. Any value >= 64 or < 0 will do.
|
||||
private const int IntTmpIndex = -1;
|
||||
private const int RorTmpIndex = -2;
|
||||
private const int CmpOptTmp1Index = -3;
|
||||
private const int CmpOptTmp2Index = -4;
|
||||
private const int VecTmp1Index = -5;
|
||||
private const int VecTmp2Index = -6;
|
||||
private const int IntTmp2Index = -7;
|
||||
private const int ReservedLocalsCount = 64;
|
||||
|
||||
public ILEmitterCtx(TranslatorCache cache, TranslatorQueue queue, TranslationTier tier, Block graph)
|
||||
private const int RorTmpIndex = ReservedLocalsCount + 0;
|
||||
private const int CmpOptTmp1Index = ReservedLocalsCount + 1;
|
||||
private const int CmpOptTmp2Index = ReservedLocalsCount + 2;
|
||||
private const int IntGpTmp1Index = ReservedLocalsCount + 3;
|
||||
private const int IntGpTmp2Index = ReservedLocalsCount + 4;
|
||||
private const int UserIntTempStart = ReservedLocalsCount + 5;
|
||||
|
||||
//Vectors are part of another "set" of locals.
|
||||
private const int VecGpTmp1Index = ReservedLocalsCount + 0;
|
||||
private const int VecGpTmp2Index = ReservedLocalsCount + 1;
|
||||
private const int UserVecTempStart = ReservedLocalsCount + 2;
|
||||
|
||||
private static int _userIntTempCount;
|
||||
private static int _userVecTempCount;
|
||||
|
||||
public ILEmitterCtx(
|
||||
MemoryManager memory,
|
||||
TranslatorCache cache,
|
||||
TranslatorQueue queue,
|
||||
TranslationTier tier,
|
||||
Block graph)
|
||||
{
|
||||
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
|
||||
_queue = queue ?? throw new ArgumentNullException(nameof(queue));
|
||||
_currBlock = graph ?? throw new ArgumentNullException(nameof(graph));
|
||||
Memory = memory ?? throw new ArgumentNullException(nameof(memory));
|
||||
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
|
||||
_queue = queue ?? throw new ArgumentNullException(nameof(queue));
|
||||
_currBlock = graph ?? throw new ArgumentNullException(nameof(graph));
|
||||
|
||||
Tier = tier;
|
||||
|
||||
|
@ -76,6 +94,16 @@ namespace ChocolArm64.Translation
|
|||
AdvanceOpCode();
|
||||
}
|
||||
|
||||
public static int GetIntTempIndex()
|
||||
{
|
||||
return UserIntTempStart + _userIntTempCount++;
|
||||
}
|
||||
|
||||
public static int GetVecTempIndex()
|
||||
{
|
||||
return UserVecTempStart + _userVecTempCount++;
|
||||
}
|
||||
|
||||
public ILBlock[] GetILBlocks()
|
||||
{
|
||||
EmitAllOpCodes();
|
||||
|
@ -145,7 +173,7 @@ namespace ChocolArm64.Translation
|
|||
_ilBlock.Add(new ILBarrier());
|
||||
}
|
||||
|
||||
private Condition GetInverseCond(Condition cond)
|
||||
private static Condition GetInverseCond(Condition cond)
|
||||
{
|
||||
//Bit 0 of all conditions is basically a negation bit, so
|
||||
//inverting this bit has the effect of inverting the condition.
|
||||
|
@ -560,17 +588,17 @@ namespace ChocolArm64.Translation
|
|||
_ilBlock.Add(new ILOpCodeStoreState(_ilBlock));
|
||||
}
|
||||
|
||||
public void EmitLdtmp() => EmitLdint(IntTmpIndex);
|
||||
public void EmitSttmp() => EmitStint(IntTmpIndex);
|
||||
public void EmitLdtmp() => EmitLdint(IntGpTmp1Index);
|
||||
public void EmitSttmp() => EmitStint(IntGpTmp1Index);
|
||||
|
||||
public void EmitLdtmp2() => EmitLdint(IntTmp2Index);
|
||||
public void EmitSttmp2() => EmitStint(IntTmp2Index);
|
||||
public void EmitLdtmp2() => EmitLdint(IntGpTmp2Index);
|
||||
public void EmitSttmp2() => EmitStint(IntGpTmp2Index);
|
||||
|
||||
public void EmitLdvectmp() => EmitLdvec(VecTmp1Index);
|
||||
public void EmitStvectmp() => EmitStvec(VecTmp1Index);
|
||||
public void EmitLdvectmp() => EmitLdvec(VecGpTmp1Index);
|
||||
public void EmitStvectmp() => EmitStvec(VecGpTmp1Index);
|
||||
|
||||
public void EmitLdvectmp2() => EmitLdvec(VecTmp2Index);
|
||||
public void EmitStvectmp2() => EmitStvec(VecTmp2Index);
|
||||
public void EmitLdvectmp2() => EmitLdvec(VecGpTmp2Index);
|
||||
public void EmitStvectmp2() => EmitStvec(VecGpTmp2Index);
|
||||
|
||||
public void EmitLdint(int index) => Ldloc(index, IoType.Int);
|
||||
public void EmitStint(int index) => Stloc(index, IoType.Int);
|
||||
|
@ -611,62 +639,12 @@ namespace ChocolArm64.Translation
|
|||
|
||||
public void EmitCallPropGet(Type objType, string propName)
|
||||
{
|
||||
if (objType == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(objType));
|
||||
}
|
||||
|
||||
if (propName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(propName));
|
||||
}
|
||||
|
||||
EmitCall(objType.GetMethod($"get_{propName}"));
|
||||
EmitCall(objType, $"get_{propName}");
|
||||
}
|
||||
|
||||
public void EmitCallPropSet(Type objType, string propName)
|
||||
{
|
||||
if (objType == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(objType));
|
||||
}
|
||||
|
||||
if (propName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(propName));
|
||||
}
|
||||
|
||||
EmitCall(objType.GetMethod($"set_{propName}"));
|
||||
}
|
||||
|
||||
public void EmitCallPrivatePropGet(Type objType, string propName)
|
||||
{
|
||||
if (objType == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(objType));
|
||||
}
|
||||
|
||||
if (propName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(propName));
|
||||
}
|
||||
|
||||
EmitPrivateCall(objType, $"get_{propName}");
|
||||
}
|
||||
|
||||
public void EmitCallPrivatePropSet(Type objType, string propName)
|
||||
{
|
||||
if (objType == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(objType));
|
||||
}
|
||||
|
||||
if (propName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(propName));
|
||||
}
|
||||
|
||||
EmitPrivateCall(objType, $"set_{propName}");
|
||||
EmitCall(objType, $"set_{propName}");
|
||||
}
|
||||
|
||||
public void EmitCall(Type objType, string mthdName)
|
||||
|
@ -684,6 +662,16 @@ namespace ChocolArm64.Translation
|
|||
EmitCall(objType.GetMethod(mthdName));
|
||||
}
|
||||
|
||||
public void EmitCallPrivatePropGet(Type objType, string propName)
|
||||
{
|
||||
EmitPrivateCall(objType, $"get_{propName}");
|
||||
}
|
||||
|
||||
public void EmitCallPrivatePropSet(Type objType, string propName)
|
||||
{
|
||||
EmitPrivateCall(objType, $"set_{propName}");
|
||||
}
|
||||
|
||||
public void EmitPrivateCall(Type objType, string mthdName)
|
||||
{
|
||||
if (objType == null)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue