aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Translation
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2019-02-24 04:24:35 -0300
committerjduncanator <1518948+jduncanator@users.noreply.github.com>2019-02-24 18:24:35 +1100
commit5001f78b1d07b988709dd5f5d1009ebe9b44c669 (patch)
treebb1307949ea9102b8ae2b68fa7e182ed7b75b2df /ChocolArm64/Translation
parenta3d46e41335efd049042cc2e38b35c4077e8ed41 (diff)
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
Diffstat (limited to 'ChocolArm64/Translation')
-rw-r--r--ChocolArm64/Translation/ILEmitterCtx.cs130
-rw-r--r--ChocolArm64/Translation/Translator.cs4
2 files changed, 61 insertions, 73 deletions
diff --git a/ChocolArm64/Translation/ILEmitterCtx.cs b/ChocolArm64/Translation/ILEmitterCtx.cs
index 54901237..f7e61bc9 100644
--- a/ChocolArm64/Translation/ILEmitterCtx.cs
+++ b/ChocolArm64/Translation/ILEmitterCtx.cs
@@ -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;
-
- public ILEmitterCtx(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));
+ private const int ReservedLocalsCount = 64;
+
+ 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)
+ {
+ 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,79 +639,39 @@ 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)
{
+ EmitCall(objType, $"set_{propName}");
+ }
+
+ public void EmitCall(Type objType, string mthdName)
+ {
if (objType == null)
{
throw new ArgumentNullException(nameof(objType));
}
- if (propName == null)
+ if (mthdName == null)
{
- throw new ArgumentNullException(nameof(propName));
+ throw new ArgumentNullException(nameof(mthdName));
}
- EmitCall(objType.GetMethod($"set_{propName}"));
+ EmitCall(objType.GetMethod(mthdName));
}
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}");
}
- public void EmitCall(Type objType, string mthdName)
- {
- if (objType == null)
- {
- throw new ArgumentNullException(nameof(objType));
- }
-
- if (mthdName == null)
- {
- throw new ArgumentNullException(nameof(mthdName));
- }
-
- EmitCall(objType.GetMethod(mthdName));
- }
-
public void EmitPrivateCall(Type objType, string mthdName)
{
if (objType == null)
diff --git a/ChocolArm64/Translation/Translator.cs b/ChocolArm64/Translation/Translator.cs
index 7f7df6e5..dd1215f5 100644
--- a/ChocolArm64/Translation/Translator.cs
+++ b/ChocolArm64/Translation/Translator.cs
@@ -138,7 +138,7 @@ namespace ChocolArm64.Translation
{
Block block = Decoder.DecodeBasicBlock(_memory, position, mode);
- ILEmitterCtx context = new ILEmitterCtx(_cache, _queue, TranslationTier.Tier0, block);
+ ILEmitterCtx context = new ILEmitterCtx(_memory, _cache, _queue, TranslationTier.Tier0, block);
string subName = GetSubroutineName(position);
@@ -153,7 +153,7 @@ namespace ChocolArm64.Translation
{
Block graph = Decoder.DecodeSubroutine(_memory, position, mode);
- ILEmitterCtx context = new ILEmitterCtx(_cache, _queue, TranslationTier.Tier1, graph);
+ ILEmitterCtx context = new ILEmitterCtx(_memory, _cache, _queue, TranslationTier.Tier1, graph);
ILBlock[] ilBlocks = context.GetILBlocks();